“。”在.symtab部分的Ndx列中的含义是什么?

add2.c:

int counter=0; int a=0; int b; int c; int add(int a, int b) { return a+b; } 

编译:gcc -c add2.c -o add2.o

阅读符号表:readelf –symbols add2.o

 Symbol table '.symtab' contains 12 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS add2.c 2: 00000000 0 SECTION LOCAL DEFAULT 1 3: 00000000 0 SECTION LOCAL DEFAULT 2 4: 00000000 0 SECTION LOCAL DEFAULT 3 5: 00000000 0 SECTION LOCAL DEFAULT 5 6: 00000000 0 SECTION LOCAL DEFAULT 4 7: 00000000 4 OBJECT GLOBAL DEFAULT 3 counter 8: 00000004 4 OBJECT GLOBAL DEFAULT 3 a 9: 00000004 4 OBJECT GLOBAL DEFAULT COM b 10: 00000004 4 OBJECT GLOBAL DEFAULT COM c 11: 00000000 14 FUNC GLOBAL DEFAULT 1 add 

“COM”在Ndx列中的含义是什么? 我理解“#”和“a”在#3部分(即.bss)中定义,“add”在#1部分(即.text)中定义,但我期待“b”和“c”也在.bss部分中定义,因此在Ndx列中得到“3”。

谢谢

gcc将未初始化的未初始化的全局变量视为“常见”符号(因此为“COM”)。

在创建最终可执行文件时,链接器将相同公共符号的多个定义(跨多个目标文件)合并在一起,以便它们都引用相同的存储。 其中一个目标文件可以将其初始化为特定值(在这种情况下,它将最终出现在数据部分中); 如果没有目标文件初始化它,将最终在BSS中; 如果多个对象初始化它,您将收到链接器错误。

总之,如果你有两个int a定义:

  • int a; 在一个对象和int a; 在另一个对象中是OK:两者都引用相同的a ,初始化为0
  • int a; 在一个对象中, int a = 42; 在另一个对象中是OK:两者都引用相同的a ,初始化为42
  • int a = 23; 在一个对象中, int a= 42; 在另一个对象中将给出链接错误。

请注意,标准C在技术上不允许在两个对象上使用相同符号的多个定义; 但许多编译器都支持它,包括gcc,作为扩展。 (它在“共同扩展”下列出 – 在C99规范中没有双关语。)

从这份PDF ,表7-11:

SHN_COMMON
相对于此部分定义的符号是常见符号,例如FORTRAN COMMON或未分配的C外部变量。 这些符号有时被称为暂定的。

另请参阅此页面 。

它们是由链接器分配的未初始化的全局变量。 有时也被称为公共变量。

编辑:嗯,保罗贝克打败了我,链接不少。 用他的答案:)