c-__forceinline生成一个函数符号-为什么?如何使它不这样做



此代码包含在某些标头"a.h"中,该标头包含:

__forceinline void f(void){}

在每个包含"a.h"的对象文件中生成一个函数符号-一个测试对象是:

#include "a.h"
void f1(void) { f(); }

使用Visual Studio 2019(社区版(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
...

MSYS2 binutils"nm"工具还报告了一个外部"T f"符号。

我正试图在微软风投中找到与GCC的相当的东西

__attribute__((always_inline))

,它不会为上述f((函数生成任何函数符号,当以上代码由gcc v11编译,__forceinline被属性((always_inline((替换,并且任何-Ox优化级别,x>0。

我更习惯GCC而不是MSVC。

请任何MSVC专家为我指明如何生成当代码中没有采用函数的地址,它不采用变参数,也不是递归的(C标准规定函数可以内联的条件(?

在我看来,这是不可能的,经过数小时的搜索MSVC文档&网状物

对我来说,使用__forceline/__attribute__((always_inline((
的全部意义在于:

A( 没有生成符号,因此没有多重定义的符号或链接问题,并且不必考虑符号应该在什么对象/库中在-中定义(尤其是对于Windows,是否需要__declspec(dllexport((。没有符号,所以没有顾虑与符号链接关联。

B( 代码仅在使用时实例化,如果未使用,则消耗0字节

C( 没有函数调用/返回开销(首先是内联的整个点(-但通过寄存器保存+恢复代码,这种节省会有所减少-(但大多数函数调用/返回机制也保存+恢复寄存器(。

MSVC所采取的方法似乎是两个世界中最糟糕的,因此必须处理符号链接问题,并且总是会生成一个函数符号,无论是否使用,都会占用空间。

请有人建议如何禁用此功能符号生成__使用MSVC强制内联声明的函数?

我想;回答";MSVC实现了与链接器的内联;即使__forceinline函数的符号是在.obj COFF对象文件中生成的,它们也不包括在输出中。EXE或。DLL文件(我检查了生成的/MAP:映射文件(,我想是由于编译器放置在函数符号上的隐藏属性。所以我很抱歉没有先调查这个-对不起。但对于任何习惯了海湾合作委员会做事方式的人来说,这都是令人困惑的。

虽然我无法回答手头的问题(我不知道如何强制MSVC避免生成符号(,但我想指出您关于__forceinline:使用的假设中的几个误解

  • "没有生成符号,因此没有多重定义的符号或链接问题"-这不需要CCD_ 2。保证普通inline函数不会导致ODR冲突,无论是否创建了实际符号
  • "该代码仅在使用时被实例化,如果不使用则消耗0字节"-你的意思是什么还不清楚。如果函数已定义(带有符号(,但未在代码中调用,则符号不会使其成为最终可执行文件,因此未使用的函数在可执行文件中不会产生空间惩罚。内联函数可能会导致代码膨胀,因为每次调用函数都会使可执行文件的大小增加所述函数的大小
  • "没有函数调用/返回开销(首先是内联的整个点(-但这种节省通过寄存器保存+恢复代码"-内联函数的最大好处不是来自调用/返回或寄存器操作,而是因为这样的函数对于优化目的是透明的。编译器不必对副作用做太多假设。事实上,无论实际的内联如何,这种好处都是存在的,因为即使对生成的符号进行了实际调用,编译器也足以知道潜在的副作用或缺乏副作用

相关内容

最新更新