2016-08-02 102 views
0

这个问题具体涉及x86架构,g++编译器和c++代码。C++将ELF文件中的类变量保存在哪里?

所以,我有以下代码:

#include <iostream> 

int second; 

class First { 
private: 
     int hello; 
public: 
     First(int number) 
     { 
      hello = number; 
     } 

     void printStuff() 
     { 
      std::cout<<this->hello<<'\n'; 
     } 
}; 

int main(int argc, char** argv) 
{ 
    First *first = new First(argc); 
    first->printStuff(); 
    second = argc; 
    return 0; 
} 

编译它像这样经过:

g++ -O0 -g class.cpp -o class

我得到的输出class二进制文件。

现在,我想知道hello存储,所以我做readelf -s ./class和输出是:

[[email protected] tmp14]$ readelf -s --wide ./class 

Symbol table '.dynsym' contains 13 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    2: 0000000000000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    3: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    4: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    5: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (3) 
    6: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (3) 
    7: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    8: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable 
    9: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 
    10: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    11: 00000000004006c0  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    12: 0000000000600dc0 272 OBJECT GLOBAL DEFAULT 26 [email protected]_3.4 (2) 

Symbol table '.symtab' contains 88 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000400200  0 SECTION LOCAL DEFAULT 1 
    2: 000000000040021c  0 SECTION LOCAL DEFAULT 2 
    3: 000000000040023c  0 SECTION LOCAL DEFAULT 3 
    4: 0000000000400260  0 SECTION LOCAL DEFAULT 4 
    5: 0000000000400288  0 SECTION LOCAL DEFAULT 5 
    6: 00000000004003c0  0 SECTION LOCAL DEFAULT 6 
    7: 0000000000400502  0 SECTION LOCAL DEFAULT 7 
    8: 0000000000400520  0 SECTION LOCAL DEFAULT 8 
    9: 0000000000400560  0 SECTION LOCAL DEFAULT 9 
    10: 0000000000400590  0 SECTION LOCAL DEFAULT 10 
    11: 0000000000400638  0 SECTION LOCAL DEFAULT 11 
    12: 0000000000400660  0 SECTION LOCAL DEFAULT 12 
    13: 00000000004006e0  0 SECTION LOCAL DEFAULT 13 
    14: 00000000004006f0  0 SECTION LOCAL DEFAULT 14 
    15: 0000000000400944  0 SECTION LOCAL DEFAULT 15 
    16: 0000000000400950  0 SECTION LOCAL DEFAULT 16 
    17: 0000000000400958  0 SECTION LOCAL DEFAULT 17 
    18: 00000000004009b0  0 SECTION LOCAL DEFAULT 18 
    19: 0000000000600b30  0 SECTION LOCAL DEFAULT 19 
    20: 0000000000600b40  0 SECTION LOCAL DEFAULT 20 
    21: 0000000000600b48  0 SECTION LOCAL DEFAULT 21 
    22: 0000000000600b50  0 SECTION LOCAL DEFAULT 22 
    23: 0000000000600d50  0 SECTION LOCAL DEFAULT 23 
    24: 0000000000600d58  0 SECTION LOCAL DEFAULT 24 
    25: 0000000000600da8  0 SECTION LOCAL DEFAULT 25 
    26: 0000000000600dc0  0 SECTION LOCAL DEFAULT 26 
    27: 0000000000000000  0 SECTION LOCAL DEFAULT 27 
    28: 0000000000000000  0 SECTION LOCAL DEFAULT 28 
    29: 0000000000000000  0 SECTION LOCAL DEFAULT 29 
    30: 0000000000000000  0 SECTION LOCAL DEFAULT 30 
    31: 0000000000000000  0 SECTION LOCAL DEFAULT 31 
    32: 0000000000000000  0 SECTION LOCAL DEFAULT 32 
    33: 0000000000000000  0 SECTION LOCAL DEFAULT 33 
    34: 0000000000000000  0 FILE LOCAL DEFAULT ABS init.c 
    35: 0000000000000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    36: 0000000000600b48  0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__ 
    37: 0000000000400720  0 FUNC LOCAL DEFAULT 14 deregister_tm_clones 
    38: 0000000000400760  0 FUNC LOCAL DEFAULT 14 register_tm_clones 
    39: 00000000004007a0  0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 
    40: 0000000000600ed0  1 OBJECT LOCAL DEFAULT 26 completed.6938 
    41: 0000000000600b40  0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fini_array_entry 
    42: 00000000004007c0  0 FUNC LOCAL DEFAULT 14 frame_dummy 
    43: 0000000000600b30  0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_entry 
    44: 0000000000000000  0 FILE LOCAL DEFAULT ABS class.cpp 
    45: 0000000000400954  1 OBJECT LOCAL DEFAULT 16 _ZStL19piecewise_construct 
    46: 0000000000600ed8  1 OBJECT LOCAL DEFAULT 26 _ZStL8__ioinit 
    47: 0000000000400835 62 FUNC LOCAL DEFAULT 14 _Z41__static_initialization_and_destruction_0ii 
    48: 0000000000400873 21 FUNC LOCAL DEFAULT 14 _GLOBAL__sub_I_second 
    49: 0000000000000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    50: 0000000000400b28  0 OBJECT LOCAL DEFAULT 18 __FRAME_END__ 
    51: 0000000000600b48  0 OBJECT LOCAL DEFAULT 21 __JCR_END__ 
    52: 0000000000000000  0 FILE LOCAL DEFAULT ABS 
    53: 0000000000400958  0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR 
    54: 0000000000600d58  0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_ 
    55: 0000000000600b40  0 NOTYPE LOCAL DEFAULT 19 __init_array_end 
    56: 0000000000600b30  0 NOTYPE LOCAL DEFAULT 19 __init_array_start 
    57: 0000000000600b50  0 OBJECT LOCAL DEFAULT 22 _DYNAMIC 
    58: 0000000000600da8  0 NOTYPE WEAK DEFAULT 25 data_start 
    59: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    60: 0000000000400940  2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini 
    61: 0000000000600ed4  4 OBJECT GLOBAL DEFAULT 26 second 
    62: 00000000004006f0 42 FUNC GLOBAL DEFAULT 14 _start 
    63: 0000000000000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    64: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    65: 0000000000400944  0 FUNC GLOBAL DEFAULT 15 _fini 
    66: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    67: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5 
    68: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5 
    69: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    70: 00000000004006c0  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    71: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable 
    72: 0000000000400950  4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 
    73: 0000000000400888 23 FUNC WEAK DEFAULT 14 _ZN5FirstC1Ei 
    74: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 
    75: 0000000000600da8  0 NOTYPE GLOBAL DEFAULT 25 __data_start 
    76: 00000000004008a0 46 FUNC WEAK DEFAULT 14 _ZN5First10printStuffEv 
    77: 0000000000400888 23 FUNC WEAK DEFAULT 14 _ZN5FirstC2Ei 
    78: 0000000000600db8  0 OBJECT GLOBAL HIDDEN 25 __TMC_END__ 
    79: 0000000000600dc0 272 OBJECT GLOBAL DEFAULT 26 [email protected]@GLIBCXX_3.4 
    80: 0000000000600db0  0 OBJECT GLOBAL HIDDEN 25 __dso_handle 
    81: 00000000004008d0 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init 
    82: 0000000000600db8  0 NOTYPE GLOBAL DEFAULT 26 __bss_start 
    83: 0000000000600ee0  0 NOTYPE GLOBAL DEFAULT 26 _end 
    84: 0000000000600db8  0 NOTYPE GLOBAL DEFAULT 25 _edata 
    85: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    86: 00000000004007e6 79 FUNC GLOBAL DEFAULT 14 main 
    87: 0000000000400638  0 FUNC GLOBAL DEFAULT 11 _init 

为了更好的可读性,我也跑这个命令:

[[email protected] tmp14]$ readelf -s --wide ./class | c++filt 

Symbol table '.dynsym' contains 13 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 FUNC GLOBAL DEFAULT UND std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@GLIBCXX_3.4 (2) 
    2: 0000000000000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    3: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    4: 0000000000000000  0 FUNC GLOBAL DEFAULT UND std::ios_base::Init::Init()@GLIBCXX_3.4 (2) 
    5: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (3) 
    6: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]_2.2.5 (3) 
    7: 0000000000000000  0 FUNC GLOBAL DEFAULT UND std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)@GLIBCXX_3.4 (2) 
    8: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable 
    9: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 
    10: 0000000000000000  0 FUNC GLOBAL DEFAULT UND operator new(unsigned long)@GLIBCXX_3.4 (2) 
    11: 00000000004006c0  0 FUNC GLOBAL DEFAULT UND std::ios_base::Init::~Init()@GLIBCXX_3.4 (2) 
    12: 0000000000600dc0 272 OBJECT GLOBAL DEFAULT 26 std::[email protected]_3.4 (2) 

Symbol table '.symtab' contains 88 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000400200  0 SECTION LOCAL DEFAULT 1 
    2: 000000000040021c  0 SECTION LOCAL DEFAULT 2 
    3: 000000000040023c  0 SECTION LOCAL DEFAULT 3 
    4: 0000000000400260  0 SECTION LOCAL DEFAULT 4 
    5: 0000000000400288  0 SECTION LOCAL DEFAULT 5 
    6: 00000000004003c0  0 SECTION LOCAL DEFAULT 6 
    7: 0000000000400502  0 SECTION LOCAL DEFAULT 7 
    8: 0000000000400520  0 SECTION LOCAL DEFAULT 8 
    9: 0000000000400560  0 SECTION LOCAL DEFAULT 9 
    10: 0000000000400590  0 SECTION LOCAL DEFAULT 10 
    11: 0000000000400638  0 SECTION LOCAL DEFAULT 11 
    12: 0000000000400660  0 SECTION LOCAL DEFAULT 12 
    13: 00000000004006e0  0 SECTION LOCAL DEFAULT 13 
    14: 00000000004006f0  0 SECTION LOCAL DEFAULT 14 
    15: 0000000000400944  0 SECTION LOCAL DEFAULT 15 
    16: 0000000000400950  0 SECTION LOCAL DEFAULT 16 
    17: 0000000000400958  0 SECTION LOCAL DEFAULT 17 
    18: 00000000004009b0  0 SECTION LOCAL DEFAULT 18 
    19: 0000000000600b30  0 SECTION LOCAL DEFAULT 19 
    20: 0000000000600b40  0 SECTION LOCAL DEFAULT 20 
    21: 0000000000600b48  0 SECTION LOCAL DEFAULT 21 
    22: 0000000000600b50  0 SECTION LOCAL DEFAULT 22 
    23: 0000000000600d50  0 SECTION LOCAL DEFAULT 23 
    24: 0000000000600d58  0 SECTION LOCAL DEFAULT 24 
    25: 0000000000600da8  0 SECTION LOCAL DEFAULT 25 
    26: 0000000000600dc0  0 SECTION LOCAL DEFAULT 26 
    27: 0000000000000000  0 SECTION LOCAL DEFAULT 27 
    28: 0000000000000000  0 SECTION LOCAL DEFAULT 28 
    29: 0000000000000000  0 SECTION LOCAL DEFAULT 29 
    30: 0000000000000000  0 SECTION LOCAL DEFAULT 30 
    31: 0000000000000000  0 SECTION LOCAL DEFAULT 31 
    32: 0000000000000000  0 SECTION LOCAL DEFAULT 32 
    33: 0000000000000000  0 SECTION LOCAL DEFAULT 33 
    34: 0000000000000000  0 FILE LOCAL DEFAULT ABS init.c 
    35: 0000000000000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    36: 0000000000600b48  0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__ 
    37: 0000000000400720  0 FUNC LOCAL DEFAULT 14 deregister_tm_clones 
    38: 0000000000400760  0 FUNC LOCAL DEFAULT 14 register_tm_clones 
    39: 00000000004007a0  0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 
    40: 0000000000600ed0  1 OBJECT LOCAL DEFAULT 26 completed.6938 
    41: 0000000000600b40  0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fini_array_entry 
    42: 00000000004007c0  0 FUNC LOCAL DEFAULT 14 frame_dummy 
    43: 0000000000600b30  0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_entry 
    44: 0000000000000000  0 FILE LOCAL DEFAULT ABS class.cpp 
    45: 0000000000400954  1 OBJECT LOCAL DEFAULT 16 std::piecewise_construct 
    46: 0000000000600ed8  1 OBJECT LOCAL DEFAULT 26 std::__ioinit 
    47: 0000000000400835 62 FUNC LOCAL DEFAULT 14 __static_initialization_and_destruction_0(int, int) 
    48: 0000000000400873 21 FUNC LOCAL DEFAULT 14 _GLOBAL__sub_I_second 
    49: 0000000000000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    50: 0000000000400b28  0 OBJECT LOCAL DEFAULT 18 __FRAME_END__ 
    51: 0000000000600b48  0 OBJECT LOCAL DEFAULT 21 __JCR_END__ 
    52: 0000000000000000  0 FILE LOCAL DEFAULT ABS 
    53: 0000000000400958  0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR 
    54: 0000000000600d58  0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_ 
    55: 0000000000600b40  0 NOTYPE LOCAL DEFAULT 19 __init_array_end 
    56: 0000000000600b30  0 NOTYPE LOCAL DEFAULT 19 __init_array_start 
    57: 0000000000600b50  0 OBJECT LOCAL DEFAULT 22 _DYNAMIC 
    58: 0000000000600da8  0 NOTYPE WEAK DEFAULT 25 data_start 
    59: 0000000000000000  0 FUNC GLOBAL DEFAULT UND std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@@GLIBCXX_3.4 
    60: 0000000000400940  2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini 
    61: 0000000000600ed4  4 OBJECT GLOBAL DEFAULT 26 second 
    62: 00000000004006f0 42 FUNC GLOBAL DEFAULT 14 _start 
    63: 0000000000000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    64: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    65: 0000000000400944  0 FUNC GLOBAL DEFAULT 15 _fini 
    66: 0000000000000000  0 FUNC GLOBAL DEFAULT UND std::ios_base::Init::Init()@@GLIBCXX_3.4 
    67: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5 
    68: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5 
    69: 0000000000000000  0 FUNC GLOBAL DEFAULT UND std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)@@GLIBCXX_3.4 
    70: 00000000004006c0  0 FUNC GLOBAL DEFAULT UND std::ios_base::Init::~Init()@@GLIBCXX_3.4 
    71: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable 
    72: 0000000000400950  4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 
    73: 0000000000400888 23 FUNC WEAK DEFAULT 14 First::First(int) 
    74: 0000000000000000  0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 
    75: 0000000000600da8  0 NOTYPE GLOBAL DEFAULT 25 __data_start 
    76: 00000000004008a0 46 FUNC WEAK DEFAULT 14 First::printStuff() 
    77: 0000000000400888 23 FUNC WEAK DEFAULT 14 First::First(int) 
    78: 0000000000600db8  0 OBJECT GLOBAL HIDDEN 25 __TMC_END__ 
    79: 0000000000600dc0 272 OBJECT GLOBAL DEFAULT 26 std::[email protected]@GLIBCXX_3.4 
    80: 0000000000600db0  0 OBJECT GLOBAL HIDDEN 25 __dso_handle 
    81: 00000000004008d0 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init 
    82: 0000000000600db8  0 NOTYPE GLOBAL DEFAULT 26 __bss_start 
    83: 0000000000600ee0  0 NOTYPE GLOBAL DEFAULT 26 _end 
    84: 0000000000600db8  0 NOTYPE GLOBAL DEFAULT 25 _edata 
    85: 0000000000000000  0 FUNC GLOBAL DEFAULT UND operator new(unsigned long)@@GLIBCXX_3.4 
    86: 00000000004007e6 79 FUNC GLOBAL DEFAULT 14 main 
    87: 0000000000400638  0 FUNC GLOBAL DEFAULT 11 _init 

我的问题是,变量first在哪里?我在转储中看不到这个对象!请注意,second是以符号61的形式存在。我预计会损坏first,但不会完全消失...

有人吗?

+1

为什么符号应该是在没有指定调试标志的输出二进制文件中?如果有什么我感到惊讶的是一个局部变量('second')存在。 –

+2

'second'是一个全局对象。 '第一个'只能作为堆栈偏移量存在 –

+0

哦,对,忽略了'second'是全局的这一事实 - 这是有道理的。 –

回答

1

example.cpp:

class Clazz { 
    int x;    // will live wherever the instance of Clazz is created 
public: 
    Clazz(const std::initializer_list<int> & data) {} 
    Clazz() : x(13) {} // "13" is either in constructor code, or .rodata 
}; 

// these will end in .data section 
// except the list parameter {1, 2, 3}, which is const and lands in .rodata 
static int localInt; // local symbol, will be in .o file only in debug info 
int globalInt;   // global symbol 
    // btw, both are initialized to 0, as they are defined in .data 
static Clazz *classPtr = nullptr; 
Clazz classInstance({1, 2, 3}); 

// all global symbols from .data/.rodata/.bss/.text (.code) sections 
// will be visible in symbol table of executable (including the "foo" below) 

// everything else defined below (except foo) is runtime allocated, 
// and can't have any fixed address in symbol table, so it will not show there. 

void foo(int param) { // param is either on stack or in register (ABI specific) 
    Clazz localVar;  // localVar instance is living on the stack space 
    classPtr = new Clazz({}); 
    // Instance of Clazz pointed at by classPtr lives in global heap memory 
    // If not released by explicit "delete classPtr;" during runtime, 
    // it will cause memory leak (avoid using naked pointers like this). 
    int localInt;  // localInt lives on stack too, uninitialized = undefined value! 
    // On the contrary to *classPtr the localVar is released upon exiting it's scope 
} 

既不堆栈或堆实例是在ELF文件,在ELF文件是唯一的代码能够操纵实例,并创建实例(无论是在堆栈或堆上,要么将其作为全局/局部变量实例化,要么通过new)。

所以,除非你将某些类型实例化为.data/.bss节(即将它定义在函数之外,作为该.cpp文件的全局/本地),否则无法确定变量的位置通过查看可执行文件的符号表保存。

在此代码只打印参数的数量
+0

完整解答。金。我混合了变量和符号。谢谢! –

2

您的对象first只是一个仅存在于堆栈中的本地对象。这些对象不存储在可执行文件的数据部分。变量second是不同的,因为它是全球性的。它被存储起来的初始值(默认值在你的情况下,因为你没有明确实例化它)并被定义为一个符号。

-1

,ARGC是参数的数目包括命令,而argv是字符串数组这是空间分隔的命令之后的话

+0

我没问过我写的代码是干什么的(; –

1

我认为,为了为了理解readelf的输出,我们首先需要了解一下编译器是如何工作的。

基本上,编译器将C/C++文件作为输出并生成可执行文件,每个C/C++通常由函数和变量构建。 为了进一步理解这一点,我们还需要讨论称为“范围”的东西,范围基本上是代码中识别的地方 - 在代码中,我们定义的对象/函数被识别并可访问。

例如,让我们利用这个代码

#include <stdio.h> 

int myGlob = 5; 

int foo() 
{ 
int a = 5; 
printf("Hey this is foo -> %d\n",a + 1); 

return a + 1; 
} 

int goo() 
{ 
int b = 5; 
printf("Hey this is goo -> %d\n",b - 1); 

return b - 1; 
} 

int main() 
{ 
printf("glob(%d) foo(%d) goo(%d)",myGlob,foo() - 1, goo() +1); 

return 0; 
} 

我们有三个功能,一个全局变量

  • foo - >这里面出现的局部变量a
  • goo - >其中有其中的局部变量b
  • main - >其中没有局部变量wit欣它
  • 我们也有myGlob这是一个全局变量

变量a只有在它foo访问,变量b这只是goo功能中访问和myGlob是,但只有所有功能中访问,所以a的范围是foob的范围是goomyGlob的范围是整个模型,相当基本吗?这就是我们在解释中会深入一些的地方。

这些函数/ GLOBAL对象中的每一个都称为符号,在编写实际代码时,您有许多模型和许多头文件调用并包含对方。编译器一次编译一个文件,并为每个编译后的模型输出一个相应的目标文件,以便允许模型识别其他模型,在每个模型中我们都包含一些称为符号表的东西,这个符号表基本上是所有函数和全局变量的集合在您的代码中应该可以被其他模型访问。

如:

  • 我们model.h定义功能foo
  • 我们model.c实现foo
  • 我们othermodel.c包括model.h定义和实施 函数foo调用goo

现在,如果我们真正创建这样的事情,并在其上运行readelf我们会看到model.h + model .c将结合model.oothermodel.c会产生othermodel.omodel.o将有其中的符号foofoo(实际的代码和指令的实施)和othermodel.o将有符号goofoo但只有实施foo 这哪里是连接踢,当连接器需要的所有目标文件组合成一个可执行文件,它读取该对象文件需要哪些内它的符号和最终我把所有的文件合并到一个可执行文件中,我再次提醒你,符号也可能是函数和全局变量。 现在我们对多个符号是什么以及为什么每个符号在多个模型示波器组合使用时有了更多的了解,我们可以理解为什么局部变量不应该有它自己的符号

让我们回到我们以前的例如,在函数foomodel.o 中有一些局部变量b,正如我们前面讲过的那样,b只能通过foo访问,为什么model.o的目标文件需要生成b的符号?除foo以外的其他代码都不能访问该变量,那么为什么需要识别或者甚至知道它的存在?

现在说实话,这是对实际发生的事情的滥用,在现实生活中,局部变量被保存在堆栈中,在您的指令代码中,当进入某些功能时,手动操作内存栈以创建一些内存缓冲区保存与执行函数有关的所有本地变量和数据......所谓的缓冲区称为栈帧,其优点在于,一旦函数退出,堆栈被清除,并且通过函数重用内存,并使用本地变量和函数元数据(例如返回地址)运行堆栈内存,与本地变量不同,全局变量(例如我的示例中的myGlob或您的second)保存在全局内存部分,所有适当的函数均可访问(实际上并不总是如此,但现在让我们保持它这个内存的生命周期贯穿整个程序,并不像堆栈内存一样被重写,每个人都可以访问它,因此局部变量不需要符号或整个生命周期程序。

如果您不知道,C++/C中的类/结构只是一堆不同类型的变量,它们依次位于内存中,如果您的类实例是本地的,它只是一堆局部变量,其他的在堆栈内存中,编译器允许你访问一些舒适的名字,最终将其转换为偏移量,因此,正如我们在前面长时间解释的那样,你根本不应该有一个符号对于一个局部变量..如果你想看到一个符号为你好,你可能已经做了作为

static int hello; 

一些诸如这或许并不会给你一个全球范围内的无障碍尚未给出您的变量整个程序的一生..

反正希望我已清除了您出头,对不起我的英语不好:)

编辑:

顺便说一句,这绝对是有与CPU架构无关,即使您为C++ PowerPC,MIPS或ARM编译代码,它也会保持不变,唯一可区分的是实际指令和函数地址,但这更像是一个概念比它与CPU架构相关