How do I get more details from VisualStudio to track down the source of a warning

275 Views Asked by At

I upgraded to the latest version of VisualStudio 2017 (15.9.5) to compile our native C++ application. However now in Release mode (and only in Release) I get the following warning (and we treat warnings as errors):

...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

DetectPossibilities is the only thing that has any relation to our code (_Temp does not), and the only thing I can see that is odd is that it is self capturing

std::function<bool(int)> DetectPossibilities;
DetectPossibilities = [&](int startPos) -> bool { 
   ... lots of code
   bool nestedAnyFound = DetectPossibilities(startPos + ofMatch.capturedLength());
   ... lots of code
};

UPDATE: I've found a workaround, and a plausible explanation, so I'm going to post the Q and the A so that the next person doesn't spend the same half-day I did to work out what's going on.

1

There are 1 best solutions below

5
gremwell On

Here's our theory about what might be happening under the hood:

std::function<bool(int)> DetectPossibilities;

Compiles (in release mode) to something equivalent to a 64 bytes allocation in memory.

DetectPossibilities = [&](int startPos) -> bool { 

Assigns a new lambda to it, this one has a capture, and this compiles (in release mode) 72 bytes of memory, but does not fit into the same spot in memory, hence the warning. The only difference is the capture. So if we make sure the original also has the capture, then we should be able to get around this strange issue.

  std::function<bool(int)> DetectPossibilities = [&](bool){return 0;};
  DetectPossibilities = [&](int startPos) -> bool {

Indeed this links in release mode, avoiding those strange errors.

Seems like a bug in Visual Studio to me, because it doesn't happen in a debug compile, and a compiler should have the smarts to be able to handle that particular pattern and allocate memory correctly.