Optimizations lost when linking against C++ libs?

Optimizations lost when linking against C++ libs?

We have a large solution in Visual Studio 2010 which comprises a Fortran exe and multiple Fortran and C++ static library projects:


                         --> MY_LIB_2 (C++)
                         --> MY_LIB_3 (Fortran)


We have encountered a problem with the run-time performance of the EXE diminishing by about 50% after modifying a C++ static library dependency.


Everything was running fine until we referenced some additional header files in one of the C++ libs.  These headers are contained in a project that does not contain any source files, only C++ header files, and therefore does not produce any compiled output of its own:


FORTRAN EXE --> MY_LIB (C++, now includes headers from headers-only project)
                         --> MY_LIB_2 (C++)
                         --> MY_LIB_3 (Fortran)


The reason that the headers-only aspect is significant is that it is not possible to set optimizations for a C++ project in Project Properties unless it contains source (.c/.cpp files) and produces some output.  However, when included elsewhere, the headers will be subject to the same optimizations as the including project.  We’re not doing anything in the code the disables optimizations (e.g. with pragmas).


After the change our code now runs about 50% as fast as it did before.  We are calling only one function in the newly included headers which carries little overhead and does not account for the slowdown.  Profiling in AQTime reveals that the slowdown is consistent throughout the code. 


What I believe may be causing this is optimizations being inadvertently disabled.  At the point the Fortran EXE is linked, we receive a large number of C4748 warnings about optimisations having been disabled in various functions defined in the newly included headers, as well as in <memory> and other cpp files that also include them (we didn’t receive these before including the additional headers):


------ Build started: Project: FortranEXEProject, Configuration: Release Win32 ------


   Creating library D:\Source\Release\FortranEXEProject.lib and object D:\Source\Release\FortranEXEProject.exp

Generating code

c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory(620) : warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function

d:\Source\CPPHeaderLibrary\header1.hpp(3231) : warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function

d:\Source\CPPSourceLibrary\source.cpp(54) : warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function



All projects have optimizations enabled and are using link-time code generation (/LTCG).


Process explorer reveals that that the Fortran linker XLink.exe is calling the C++ linker, LINK.exe. 


Can you explain what is happening here please, and how to ensure that optimizations in linked C++ code are maintained?


Thanks in advance.

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Are you using the Microsoft C++ compiler or the Intel one? Do you have inter-procedural optimisation turned on at the compilation stage (/Qpio) for all projects?

link.exe is just the windows linker - it is not C++ specific.

IPO is initiated at Link time. IPO is valid for files compiled with the IPO option as this generates data for use by the linker. Changing or adding a header may set something in the ipo data base to indicate the header file had not been compiled with something with IPO enabled. (this is all supposition by the way). If this is true, then create a C++ project (e.g. static library) that compiles a dummy function that includes these header files .AND. enables IPO. See if this corrects the problem.

I also noted that in the Version 12 of the ICC compiler that under some circumstances IPO would fail to inline some functions attributed with __inline. Using __forceinline would correct for this. I cannot ascertain as to if this is your problem or not.

Jim Dempsey

Thanks both for the replies. We are using the Microsoft C++ compiler. In the end we noticed that optimisations had been disabled in a couple of our C++ static library projects further down the call graph which included the new headers. Turning optimisations back on has fixed the problem; what distracted us was LINK.EXE being invoked by XLINK - Ian, thanks for the clarification on that. For info, setting inter-procedural optimisation in our Fortran EXE project didn't have any effect on performance so we will retain the default setting for the time being. Good to know about for the future though.

Leave a Comment

Please sign in to add a comment. Not a member? Join today