Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Suspicious Optimization Behavior - LNK2019 inline virtual destructors

Teodor_H_
Beginner
1,983 Views

I have following code:

//ivirtualbase.hh
#pragma once
#ifdef _build_dll
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
class IVirtualBase
{
public:
    virtual ~IVirtualBase(){};
    virtual void speak() = 0;
};

//virtualclass.hh
#pragma once
#ifdef _build_dll
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
class IVirtualBase
{
public:
    virtual ~IVirtualBase(){};
    virtual void speak() = 0;
};

//concreteclass.hh
#pragma once
#include "ivirtualbase.hh"
#include "virtualclass.hh"

class DLLEXPORT ConcreteClass : public VirtualClass
{
public:
    ConcreteClass(int nn);
    void speak();
    void eat();
    virtual ~ConcreteClass();
private:
    int n;
};

//concreteclass.cpp
#include "concreteclass.hh"
#include <iostream>
ConcreteClass::ConcreteClass(int nn)
{
    n = nn;
}
void ConcreteClass::eat()
{
    n = n - 1;
    std::cout << "Eating 1 n now is " << n << std::endl;
}
void ConcreteClass::speak()
{
    std::cout << "n is " << n << std::endl;
}
ConcreteClass::~ConcreteClass()
{
    std::cout << "destroyed" << std::endl;
}

This code is compiled in a DLL using the following flags:

Compiler:

/GS /Qopenmp /GA /Qansi-alias /Wall /QxHost /Zc:wchar_t /O1 /Qintel-extensions- /Ob2 
/Fd"x64\Release\vc120.pdb" /D "_MBCS" /D "_build_dll" /D "_WINDLL" 
/Qstd=c++11 /Zc:forScope /Oi /MD /Fa"x64\Release\" /EHsc /nologo /Qparallel /Fo"x64\Release\"
/Qprof-dir "x64\Release\" /FA /Wpch-messages- /Fp"x64\Release\Project1.pch" 

Linker:

/OUT:"c:\users\thanchevici\documents\visual studio 2013\Projects\Project1\x64\Release\Project1.dll" /MANIFEST /NXCOMPAT 
/PDB:"c:\users\thanchevici\documents\visual studio 2013\Projects\Project1\x64\Release\Project1.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" 
/IMPLIB:"c:\users\thanchevici\documents\visual studio 2013\Projects\Project1\x64\Release\Project1.lib" /DLL 
/MACHINE:X64 /OPT:NOREF /MANIFESTUAC:"level='asInvoker' uiAccess='false'" 
/ManifestFile:"x64\Release\Project1.dll.intermediate.manifest" /OPT:ICF /NOLOGO /TLBID:1 

Library compiles and links without error.

The test program however fails to link

#include "concreteclass.hh"
int main()
{
    ConcreteClass c(10);
    c.speak();
    c.eat();
    return 0;
}

Compiled with:

/GS /W3 /Gy /Zc:wchar_t 
/I"C:\Users\thanchevici\Documents\Visual Studio 2013\Projects\Project1\Project1" 
/O1 /Ob2 /Fd"x64\Release\vc120.pdb" /D "_MBCS" 
/Zc:forScope /Oi /MD /Fa"x64\Release\" /EHsc 
/nologo /Fo"x64\Release\" /Qprof-dir "x64\Release\" /Fp"x64\Release\project2.pch" 

Linked with:

/OUT:"c:\users\thanchevici\documents\visual studio 2013\Projects\Project1\x64\Release\project2.exe" 
/MANIFEST /NXCOMPAT 
/PDB:"c:\users\thanchevici\documents\visual studio 2013\Projects\Project1\x64\Release\project2.pdb" 
/DYNAMICBASE "Project1.lib" "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:X64 /OPT:REF /SUBSYSTEM:CONSOLE 
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" 
/ManifestFile:"x64\Release\project2.exe.intermediate.manifest"
/OPT:ICF /NOLOGO /LIBPATH:"C:\Users\thanchevici\Documents\Visual Studio 2013\Projects\Project1\x64\Release" 
/TLBID:1 

The error is

error LNK2019: unresolved external symbol "public: virtual __cdecl IVirtualBase::~IVirtualBase(void)" (??1IVirtualBase@@UEAA@XZ) referenced in function main

Disabling optimization makes the error disappear.

Can you please comment on this behavior?

Thank you

Teodor

0 Kudos
24 Replies
Yuan_C_Intel
Employee
232 Views

Hi, Teodor

I can reproduce the linker error now when /fast is set. It was not set in the attached file in Post #5.

/fast includes /O3/Qipo/Qprec-div-/fp:fast=2, and /QxHost.

The link error is caused by flag /Qipo, the inter-procedure optimization. I will escalate this to engineer and let you know for an update.

Thanks.

0 Kudos
Teodor_H_
Beginner
232 Views

Hi Yolanda,

on my system i can reproduce it with the following flags: /

Qstd=c++11 /Qm64 /GR /MD /EHa /nologo /Ob1 /c /Od

d:\temp\intel\test>nmake /f mydll.nmake mydll

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        icl /GR /MD /EHa /nologo /Ob1 /c /LD  /Qstd=c++11 /Qm64 /Od  /D_build_dll /D_WINDLL concreteclass.cpp
concreteclass.cpp
        xilink /OUT:mydll.dll /IMPLIB:mydll.lib  /DLL /MANIFEST /MACHINE:X64 /NOLOGO /LIBPATH:. /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"mydll.dll.intermediate.manifest" concreteclass.obj
   Creating library mydll.lib and object mydll.exp

d:\temp\intel\test>nmake /f myexe.nmake myexe

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        icl /GR /MD /EHa /nologo /Ob1 /c /Qstd=c++11 /Qm64 /Od  main.cpp
main.cpp
        xilink /OUT:myexe.exe /SUBSYSTEM:CONSOLE  /MANIFEST /MACHINE:X64 /NOLOGO /LIBPATH:. /MANIFESTUAC:"level='asInvoker' uiAccess='false'" "mydll.lib" /ManifestFile:"myexe.exe.intermediate.manifest" main.obj
main.obj : error LNK2019: unresolved external symbol "public: virtual __cdecl IVirtualBase::~IVirtualBase(void)" (??1IVirtualBase@@UEAA@XZ) referenced in function "public: virtual void * __cdecl ConcreteClass::`scalar deleting destructor'(unsigned int)" (??_GConcreteClass@@UEAAPEAXI@Z)
myexe.exe : fatal error LNK1120: 1 unresolved externals
NMAKE : fatal error U1077: '"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.0.109\windows\bin\intel64\xilink.EXE"' : return code '0x460'
Stop.

d:\temp\intel\test>

However, adding /Qinline-dllimport- solves the problem. Application links with /fast as well.

d:\temp\intel\test>nmake /f mydll.nmake mydll

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        icl /GR /MD /EHa /nologo /Ob1 /c /LD  /Qstd=c++11 /Qm64 /Qinline-dllimport- /fast  /D_build_dll /D_WINDLL concreteclass.cpp
concreteclass.cpp
        xilink /OUT:mydll.dll /IMPLIB:mydll.lib  /DLL /MANIFEST /MACHINE:X64 /NOLOGO /LIBPATH:. /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"mydll.dll.intermediate.manifest" concreteclass.obj
   Creating library mydll.lib and object mydll.exp

d:\temp\intel\test>nmake /f myexe.nmake myexe

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        icl /GR /MD /EHa /nologo /Ob1 /c /Qstd=c++11 /Qm64 /Qinline-dllimport- /fast  main.cpp
main.cpp
        xilink /OUT:myexe.exe /SUBSYSTEM:CONSOLE  /MANIFEST /MACHINE:X64 /NOLOGO /LIBPATH:. /MANIFESTUAC:"level='asInvoker' uiAccess='false'" "mydll.lib" /ManifestFile:"myexe.exe.intermediate.manifest" main.obj

d:\temp\intel\test>

Please let me know if you need any additional information.

Thank you,

Teodor

0 Kudos
Yuan_C_Intel
Employee
232 Views

Hi, Teodor

I cannot reproduce the error with the new option you provided without /fast. I'm using VS2013 + ICL 17.0.0.109. Are you using command prompts from Intel(R) Parallel Studio XE 2017 start menu? And the error does not look the same as previous ipo error and warning.

>nmake -F mydll.nmake mydll

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        icl /GR /MD /EHa /nologo /Ob1 /c /Od /Qstd=c++11 /Qm64   /D_build_dll /D
_WINDLL concreteclass.cpp
concreteclass.cpp
        xilink /OUT:mydll.dll /IMPLIB:mydll.lib  /DLL /MANIFEST /MACHINE:X64 /NO
LOGO /LIBPATH:. /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:
"mydll.dll.intermediate.manifest" concreteclass.obj
   Creating library mydll.lib and object mydll.exp

>nmake -F myexe.nmake clean

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        del main.obj myexe.exp myexe.exe myexe.*.manifest

>nmake -F myexe.nmake myexe

Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        icl /GR /MD /EHa /nologo /Ob1 /c /Od /Qstd=c++11 /Qm64   main.cpp
main.cpp
        xilink /OUT:myexe.exe /SUBSYSTEM:CONSOLE  /MANIFEST /MACHINE:X64 /NOLOGO
 /LIBPATH:. /MANIFESTUAC:"level='asInvoker' uiAccess='false'" "mydll.lib" /Manif
estFile:"myexe.exe.intermediate.manifest" main.obj

The /Qinline-dllimport- disables inline of dllimport functions, while a major functionality of IPO is inlining. /Qinline-dllimport- can be a workaournd for this issue. They still have some connections. 

Hope this helps.

Thanks.

0 Kudos
Teodor_H_
Beginner
232 Views

Hi Yolanda,

yes i am using the shortcut in the start menu (Intel(R) 64 Visual Studio 2013). I am using /Qinline-dllimport- for the moment.

C:\Program Files (x86)\IntelSWTools>which icl
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.0.109\windows\bin\intel64\icl.EXE
C:\Program Files (x86)\IntelSWTools>which cl
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\amd64\cl.EXE
C:\Program Files (x86)\IntelSWTools>which link
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\amd64\link.EXE
C:\Program Files (x86)\IntelSWTools>which xilink
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.0.109\windows\bin\intel64\xilink.EXE
C:\Program Files (x86)\IntelSWTools>set INT
INTELGTDEBUGGERROOT=C:\Program Files (x86)\IntelSWTools\debugger_2017\gdb\intel64_igfx\
C:\Program Files (x86)\IntelSWTools>cl
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.40629 for x64
C:\Program Files (x86)\IntelSWTools>icl
Intel(R) C++ Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 17.0.0.109 Build 20160721

regards,

Teodor

0 Kudos
Reply