Как получить более подробную информацию из VisualStudio, чтобы отследить источник предупреждения
Я обновил до последней версии VisualStudio 2017 (15.9.5), чтобы скомпилировать наше родное приложение C++. Однако теперь в режиме Release (и только в Release) я получаю следующее предупреждение (и мы рассматриваем предупреждения как ошибки):
...nothing useful...
6>qrc_IceApplication.cpp
6> Creating library C:/tkbt/Prose/Build/Release/lib/Prose.lib and object C:/tkbt/Prose/Build/Release/lib/Prose.exp
6>Generating code
6>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\functional(1195): error C2220: warning treated as error - no 'executable' file generated
6>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\functional(1195): warning C4789: buffer '_Temp' of size 64 bytes will be overrun; 72 bytes will be written starting at offset 8
6>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\functional(1195): warning C4789: buffer '_Temp' of size 64 bytes will be overrun; 72 bytes will be written starting at offset 8
6>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\functional(1195): warning C4789: buffer '_Temp' of size 64 bytes will be overrun; 72 bytes will be written starting at offset 8
6>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\functional(1195): warning C4789: buffer 'DetectPossibilities' of size 64 bytes will be overrun; 72 bytes will be written starting at offset 8
6>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\functional(1195): warning C4789: buffer '_Temp' of size 64 bytes will be overrun; 72 bytes will be written starting at offset 8
DetectPossabilities - это единственное, что имеет какое-либо отношение к нашему коду (_Temp нет), и единственное, что я вижу странным, это то, что он самозахватывает
std::function<bool(int)> DetectPossibilities;
DetectPossibilities = [&](int startPos) -> bool {
... lots of code
bool nestedAnyFound = DetectPossibilities(startPos + ofMatch.capturedLength());
... lots of code
};
ОБНОВЛЕНИЕ: я нашел обходной путь и правдоподобное объяснение, поэтому я собираюсь опубликовать вопросы и ответы, чтобы следующий человек не потратил те же полдня, которые я потратил, чтобы разобраться, что происходит.
1 ответ
Вот наша теория о том, что может происходить под капотом:
std::function<bool(int)> DetectPossibilities;
Компилирует (в режиме выпуска) что-то эквивалентное выделению 64 байта в памяти.
DetectPossibilities = [&](int startPos) -> bool {
Присваивает ему новую лямбду, эта имеет перехват и компилирует (в режиме выпуска) 72 байта памяти, но не помещается в то же место в памяти, отсюда и предупреждение. Единственная разница - захват. Так что, если мы убедимся, что оригинал также имеет захват, то мы сможем обойти эту странную проблему.
std::function<bool(int)> DetectPossibilities = [&](bool){return 0;};
DetectPossibilities = [&](int startPos) -> bool {
На самом деле это ссылки в режиме выпуска, избегая тех странных ошибок.
Для меня это похоже на ошибку в Visual Studio, потому что это не происходит в отладочной компиляции, и компилятор должен иметь умные способности, чтобы иметь возможность обрабатывать этот конкретный шаблон и правильно распределять память.