为什么C静态函数不';不转到文本部分,而是转到rodata部分?
我在C源文件中定义了一些静态函数。编译后,我使用nm工具显示.o文件中的所有符号,发现我定义的所有静态函数都在rodata部分,它们的符号名称是func.xxxx。函数不应该位于文本函数中吗 以下是显示静态功能的nm命令的结果。func.xxxx前面的“r”表示函数存储在rodata节中为什么C静态函数不';不转到文本部分,而是转到rodata部分?,c,gcc,compilation,C,Gcc,Compilation,我在C源文件中定义了一些静态函数。编译后,我使用nm工具显示.o文件中的所有符号,发现我定义的所有静态函数都在rodata部分,它们的符号名称是func.xxxx。函数不应该位于文本函数中吗 以下是显示静态功能的nm命令的结果。func.xxxx前面的“r”表示函数存储在rodata节中 00000000 t desc_to_mattr U __do_panic 00000000 r __func__.5546 00000000 r __func__.5554 00000000
00000000 t desc_to_mattr
U __do_panic
00000000 r __func__.5546
00000000 r __func__.5554
00000000 r __func__.5560
00000000 r __func__.5565
00000000 r __func__.5604
00000000 r __func__.5638
00000000 r __func__.5698
00000000 r __func__.5710
00000000 r __func__.5719
00000000 r __func__.5729
00000000 r __func__.5758
以下是我的gcc选项:
arm-linux-gnueabihf-gcc -std=gnu99 -Werror -fdiagnostics-show-option -Wall -Wcast-align -Werror-implicit-function-declaration -Wextra -Wfloat-equal -Wformat-nonliteral -Wformat-security -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wshadow -Wstrict-prototypes -Wswitch-default -Wwrite-strings -Wno-missing-field-initializers -Wno-format-zero-length -Waggregate-return -Wredundant-decls -Wold-style-definition -Wstrict-aliasing=2 -Wundef -pedantic -Wdeclaration-after-statement -Os -g -ffunction-sections -fdata-sections -pipe -g3 -mcpu=cortex-a9 -mfloat-abi=soft -funwind-tables -mthumb -mthumb-interwork -fno-short-enums -fno-common -mno-unaligned-access -MD -MF
您观察到的符号并不指向函数,而是指向函数的名称。您可能会在这些静态函数中使用宏
\uuuu func\uu
,从而创建这些符号
例如:
printf("%s: %s\n", __func__, somemsg);
将导致这些符号的产生。它可能会被类似宏的
#define FUNC_ENTRY printf("%s entered\n", __func__);
或者类似的,所以它可能不直接可见
静态函数本身在符号表中通常不可见,因为它们不能从外部链接。@M.M链接器是否可以看到
静态
函数?很可能它们是由编译器处理的,而链接器甚至从未见过它们。如果您只定义函数而不使用它,它不一定会去任何地方:编译器可能会当场删除它。如果您只使用它一次,那么不管它有多长,它都有可能被编译器内联,并且不会像上面那样编译任何独立版本。关键是,当你说static
时,编译器已经知道函数的所有用法,并且可以相应地进行优化。你认为\uuuu func\uuu
是什么意思?您必须知道,因为它存在于您的C代码中。@Lundin但它可能会被某些库等的宏所掩盖。@cmaster,我想您是对的,我只使用静态函数一次,它应该由编译器内联。谢谢。让我困惑的是.o文件没有包含静态函数的符号。现在我认为@cmaster是对的:因为静态函数只使用一次,它是由编译器内联的。@shijunzhao这没关系,不管函数发生了什么,名称都存储在这样的符号中。@shijunzhao这与静态或内联完全无关,如回答所示<代码>\uuuu func\uuuuu在.rodata
中生成文本字符串,这就是你看到的,很简单。嗨,@Ctx你说静态函数通常在符号表中不可见,那么它们通常是内联的吗?@shijunzhao这是由编译器处理的,与符号表无关。编译器甚至可以选择内联一个非静态函数,并另外提供一个全局可见的实例。这取决于此函数的代码大小、使用次数和优化参数。