Reputation: 655
This code in some header 'a.h' that is multiply included:
__forceinline void f(void){}
Produces a function symbol in every object file that includes 'a.h' - a test object is:
#include "a.h"
void f1(void) { f(); }
Compiling this into an object file with Visual Studio 2019 (Community Ed.) v16.10.1 :
$ CL /std:c17 /TC /O2 /c t_inl_a.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30037 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
t_inl_a.c
$
$ DUMPBIN /SYMBOLS t_inl_a.obj
Microsoft (R) COFF/PE Dumper Version 14.29.30037.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file t_inl_a.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
...
00E 00000000 SECT3 notype () External | _f
00F 00000000 SECT5 notype () External | _f1
...
The MSYS2 binutils 'nm' tool also reports an external ' T f ' symbol.
I am trying to find something in MSVC that is equivalent to GCC's
__attribute__((always_inline))
, which does NOT generate any function symbol for the above f() function, when the above code is compiled by gcc v11 with __forceinline replaced by attribute((always_inline)), and any -Ox optimization level, x > 0 .
I am much more used to GCC than MSVC.
Would any MSVC expert please be able to point me in the direction of how to generate symbol-less always-integrated-into-caller-function functions with MSVC, when no address of the function is taken in the code, and it is does not take variadic parameters, and is not recursive (conditions under which C standard says that functions are able to be inlined) ?
It does not seem to me to be possible, after hours of scouring the MSVC documentation & web .
To me, the whole point of using __forceline / __attribute__((always_inline))
is that:
A) No symbol is generated, so that one has no multiply-defined-symbol or linkage issues, and does not have to think in what object / library the symbol should be defined in - ( and particularly for Windows, whether it needs __declspec(dllexport) or not ) . There is no symbol, so no concerns associated with symbol linkage .
B) The code is only instantiated when used, consuming 0 bytes if not used
C) No function call / return overhead (the whole point of inline in the first place) - but this saving is somewhat lessened by register save + restore code - (but most function call/return mechanisms also save+restore the registers) .
The approach taken by MSVC would seem to be the worst of both worlds, so one does have to deal with symbol linkage issues and there is always a function symbol generated, taking up space whether it is used or not.
Please can anyone suggest how to disable this function symbol generation for __forceinline declared functions with MSVC ?
Upvotes: 0
Views: 935
Reputation: 655
I guess the "answer" is that MSVC implements inlining with the linker; even though the symbols for __forceinline functions are generated in .obj COFF object files, they are not included in output .EXE or .DLL files ( I checked the /MAP: map files produced ), I guess due to the hidden attributes placed on the function symbols by the compiler. So my bad for not investigating this first - sorry. But it is confusing for anyone used to GCC's way of doing things.
Upvotes: 1
Reputation: 62553
While I can't answer question at hand (I would not know how to force MSVC to avoid generating a symbol), I would like to point out to several misconceptions in your assumptions regarding uses of __forceinline
:
__forceinline
. A plain inline
function is guaranteed to not cause ODR violations, regardless of whether actual symbol was created or not.Upvotes: 0