I am testing the use of Intel C++ Compiler 19.1 with Visual Studio 2019 with my fairly large application. I am having problems with virtual functions in very specific situations that I do not have with the Microsoft compiler in VS, or with GCC on both Linux and Mac. This is a framework that I have been using for years without problems and (SFAIK) everything is fine (no compiler errors/warnings on any compiler, including Intel).
The problem arises with a virtual function from a base class which is resolved in an intermediate class, for example, ETable has virtual function Special Setup (which is an empty function), the working function is in subclass ETableEdit, which has an subclass ETableEditDocument. SpecialSetup out of an ETable function calls the correct SpecialSetup in ETableEdit, but the <<this>> in ETableEdit::SpecialSetup isn't correct: the pointer is 0x0625dda0 when it should be 0x0625ddb0, and this causes a run-time exception. I've found at least a half-dozen such problems and they all have the same issue: a virtual function from a base class is resolved in an intermediate class where the <<this>> pointer is off by a relatively small offset (typically 8 or 16). I have unsuccessfully tried creating a simple example of this, so I'm not sure what else it is about these classes that triggers the error.
- Development Tools
- Intel® C++ Compiler
- Intel® Parallel Studio XE
- Intel® System Studio
- Parallel Computing
While I haven't been able to produce a modest-sized example which creates a crash, I think I can show an example which shows what I think to be the issue. The attached C++ file, when compiled using Intel C++ 19.1 will produce an ELockedHandle/EMemoryHandle class which only includes two elements in its vtable (for ~ and for NewSubObject), with nothing for the virtual KillSubObject. The same class (fully defined in my overall project; this doesn't do everything) includes all three virtual functions. The full project has 100's of source files with separate header files for those classes. I'm thinking that somehow the compiler is doing a shorter vtable for a class in some source files than in others, which causes a crash when it calls across source files. (Thus the single file can't seem to reproduce it). I haven't found any option which seems to control whether the compiler can try to optimize away a vtable element.
The compiler command line is
/permissive- /GS /W3 /Zc:wchar_t /Zi /Od /Fd"Debug\vc142.pdb" /Zp8 /D "_DEBUG" /D "_CONSOLE" /D "_CRT_SECURE_NO_WARNINGS" /Zc:forScope /Gd /MTd /std:c++17 /FC /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Qprof-dir "Debug\" /Fp"Debug\TestVirtual.pch"
The linker command line is
/OUT:"C:\Users\tomd\source\repos\TestVirtual\Debug\TestVirtual.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\tomd\source\repos\TestVirtual\Debug\TestVirtual.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /SAFESEH /INCREMENTAL /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\TestVirtual.exe.intermediate.manifest" /NOLOGO /TLBID:1
I couldn't see anything wrong from compiling the source file. We will need to have a test case to reproduce the runtime crash in order to figure out what might cause the problem.
I know that this doesn't produce a crash (I explained that above), but doesn't it produce object code with a vtable which includes only two of the three virtual functions? Why would that be?