这个问题特别涉及x86架构,g++
编译器和c++
代码。
所以,我有以下代码:
#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
,输出为:
[ishaypeled@escorpio 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 _ZNSolsEi@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 _ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (3)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_2.2.5 (3)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c@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 _Znwm@GLIBCXX_3.4 (2)
11: 00000000004006c0 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4 (2)
12: 0000000000600dc0 272 OBJECT GLOBAL DEFAULT 26 _ZSt4cout@GLIBCXX_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 _ZNSolsEi@@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 _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
67: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_2.2.5
68: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@@GLIBC_2.2.5
69: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c@@GLIBCXX_3.4
70: 00000000004006c0 0 FUNC GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev@@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 _ZSt4cout@@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 _Znwm@@GLIBCXX_3.4
86: 00000000004007e6 79 FUNC GLOBAL DEFAULT 14 main
87: 0000000000400638 0 FUNC GLOBAL DEFAULT 11 _init
为了更好的可读性,我还运行了这个命令:
[ishaypeled@escorpio 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 __libc_start_main@GLIBC_2.2.5 (3)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@GLIBC_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::cout@GLIBCXX_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 __libc_start_main@@GLIBC_2.2.5
68: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@@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::cout@@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
的错误,但不会完全消失...
任何?
答案 0 :(得分:2)
您的对象first
只是一个仅存在于堆栈中的本地对象。这些对象不存储在可执行文件的数据部分中。变量second
是不同的,因为它是全局的。它以其初始值存储(在您的情况下为默认值,因为您没有显式实例化它)并被定义为符号。
答案 1 :(得分: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文件的全局/局部),否则无法确定变量将保留在何处通过查看可执行文件的符号表。
答案 2 :(得分:1)
我认为为了理解readelf的输出,我们首先需要了解编译器的工作原理。
基本上编译器将C / C ++文件作为输出并生成可执行文件,每个C / C ++通常由函数和变量构成。 为了进一步理解这一点,我们还需要讨论称为&#34;范围&#34;范围基本上是代码中的识别位置 - 在我们的代码中,我们定义的对象/函数被识别和访问。
例如,让我们使用此代码
#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;
}
我们有三个函数和一个全局var
foo
- &gt;其中包含局部变量a
goo
- &gt;其中包含局部变量b
myGlob
这是一个全局变量变量a
只能在foo
变量b
中访问,变量goo
只能在myGlob
函数中访问,a
可在所有函数中访问但仅限于此,因此foo
的范围b
goo
的范围为myGlob
,model.h
的范围是整个模型,非常基本正确吗?这是我们在解释中更深入的地方。
这些函数/ GLOBAL对象中的每一个都被称为符号,在编写实际代码时,您有许多模型和许多头文件调用并相互包含。编译器一次编译一个文件并输出每个编译模型的相应目标文件,以便模型识别其他模型,在每个模型中我们都包含一个称为符号表的东西,它基本上是所有函数和全局变量的集合您的代码中应该可以被其他模型访问。
e.g:
foo
定义了函数model.c
foo
实施了othermodel.c
model.h
包含goo
定义和实现
调用model.h
现在,如果我们实际创建这样的内容并运行readelf,我们会看到model .c
+ model.o
将合并到othermodel.c
而othermodel.o
会生成{{ 1}},model.o
将在其中包含符号foo
和foo
(实际代码和说明)的实现,而othermodel.o
将包含符号goo
和foo
但只有实施
foo
的
这是链接器启动的地方,当链接器需要将所有目标文件组合成可执行文件时,它会读取哪个目标文件需要哪个符号并最终将所有文件合并为一个可执行文件,我再次提醒您符号也可能是函数和全局变量。
既然我们对多少模型范围的组合使用了什么符号以及为什么每个符号的使用有了更多的了解,我们就能理解为什么局部变量不应该有它自己的符号
让我们回到前面的示例,在foo
的{{1}}函数中
有一些局部变量model.o
,因为我们之前已经说过b只能由foo访问,为什么b
的目标文件需要生成model.o
的符号?除b
中的代码外,没有其他人可以访问该变量,那么为什么需要识别甚至知道它的存在?
现在老实说,有点滥用实际发生的事情,在现实生活中,局部变量被保存在堆栈中,在你的指令代码中,当你输入一些函数时你的内存堆被手动操作以创建一些内存缓冲区,用于保存与执行函数有关的所有局部变量和数据...所谓的缓冲区称为堆栈帧,其优点是一旦退出函数,清除堆栈,重新执行函数 - 使用该内存并使用其局部变量和函数元数据(例如返回地址)运行堆栈内存,与局部变量不同,全局变量(例如我的示例中的foo
或您的myGlob
中的全局变量保存在所有适当功能都可以访问的全局内存部分(实际上并非总是如此,但现在让它保持简单),并且内存的生命周期贯穿整个程序,它并没有。像堆栈内存一样不断重写,每个人都可以加入因此,本地变量不需要符号或整个程序的生命周期。
如果你不知道,C ++ / C中的类/结构只是一堆不同类型的变量按顺序排列在内存中,如果你的类实例是本地的,它只是一堆局部变量坐着在堆栈内存中一个接一个地使用,编译器允许您使用一些最终转换为偏移的舒适名称进行访问,因此,正如我们在我长期以来的长篇解释中所说的那样,您根本就不应该这样做\赢得了一个局部变量的符号..如果你想看到你好的符号,你可以做一些像
这样的事情。second
它可能没有为您提供全局范围的可访问性,但却为您的变量提供整个程序的生命周期..
无论如何希望我已经把你清理干净了,抱歉我的英语能力差:)
修改强>
顺便说一句,这绝对与你的CPU架构无关,即使你为C ++ PowerPC,MIPS或ARM编译代码,它也会保持不变,唯一可以区分的是实际的指令,也许函数的地址,但这更像是一个与CPU架构相关的概念
答案 3 :(得分:-1)
在这段代码中你只打印参数的数量,argc是包含命令的参数个数,而argv是字符串数组,它是按空格分隔的单词之后