【问题标题】:Why C static functions doesn't go to text section but to rodata section?为什么 C 静态函数不去文本部分而是去rodata部分?
【发布时间】:2017-09-21 07:49:26
【问题描述】:

我在 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 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 

【问题讨论】:

  • @M.M static 函数对链接器可见吗?很可能它们由编译器处理,而链接器甚至看不到它们。
  • 如果你只是定义函数但不使用它,它不一定会去任何地方:它可能会被编译器当场丢弃。如果你只使用它一次,它很可能会被编译器内联不管它有多长,并且不会像上面那样编译任何独立版本。关键是,当您说static 时,编译器已经知道该函数的所有 用途,并且可以进行相应的优化。
  • 您认为__func__ 是什么意思?您必须知道,因为它存在于您的 C 代码中。
  • @Lundin 但它可能会被某些库等的某些宏所掩盖......
  • @cmaster,我想你是对的,我只使用了一次静态函数,它应该被编译器内联。谢谢。

标签: c gcc compilation


【解决方案1】:

您观察到的符号并不指向函数,而是指向函数的名称。您可能在这些静态函数中使用了宏 __func__,这会导致创建这些符号。

例如:

printf("%s: %s\n", __func__, somemsg);

将导致这些符号的创建。它可能会被类似的宏所掩盖

#define FUNC_ENTRY printf("%s entered\n", __func__);

或类似的,所以它可能不直接可见。

静态函数本身通常在符号表中不可见,因为它们无法与外部链接。

【讨论】:

  • 令我困惑的是 .o 文件不包含静态函数的符号。现在我认为@cmaster 是对的:因为静态函数只使用一次,所以它被编译器内联。
  • @shijunzhao 这没关系,无论函数发生什么,名称都存储在这样的符号中。
  • @shijunzhao 这与静态或内联完全无关,如this answer所示。 __func__.rodata 中生成文本字符串,这就是你所看到的,就这么简单。
  • HI,@Ctx 你说静态函数在符号表中通常是不可见的,那么它们通常是内联的吗?
  • @shijunzhao 这是编译器的配置,与符号表无关。编译器甚至可以选择内联非静态函数另外提供它的全局可见实例。这取决于这个函数的代码大小、使用次数和优化参数。
猜你喜欢
  • 1970-01-01
  • 2018-10-06
  • 2021-05-29
  • 2017-02-10
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多