C++ C++;-函数的全局指针
为什么会这样?我认为全局数据在编译时被“初始化”(编译器以obj文件格式null字节保存到.global节,因此当该节加载到内存中时,它被初始化为null)。那个么,若编译器在运行时不知道函数在内存中的位置,那个么如何初始化指向函数地址的指针呢C++ C++;-函数的全局指针,c++,c,pointers,C++,C,Pointers,为什么会这样?我认为全局数据在编译时被“初始化”(编译器以obj文件格式null字节保存到.global节,因此当该节加载到内存中时,它被初始化为null)。那个么,若编译器在运行时不知道函数在内存中的位置,那个么如何初始化指向函数地址的指针呢 #include <iostream> void vypis(); int neco; int * bla = &neco; void (*vypis_ptr)() = vypis; int main(int argc, con
#include <iostream>
void vypis();
int neco;
int * bla = &neco;
void (*vypis_ptr)() = vypis;
int main(int argc, const char * argv[])
{
}
void vypis() {
}
#包括
void vypis();
int neco;
int*bla=&neco;
void(*vypis_ptr)()=vypis;
int main(int argc,const char*argv[]
{
}
void vypis(){
}
我删除了iostream
的冗余include,因此您的源代码实际上编译为C,并在我的系统上将其编译为一个名为vypis的可执行文件。以下是我的发现:
$nm vypis | fgrep vypis
0000000000 4004D0吨vypis
0000000000 600888 D vypis\u ptr
因此,vypis
,一个函数,在“文本”部分是一个全局函数,vypis\u ptr
,一个指向函数的指针,在“数据”部分是一个全局函数
数据部分中的对象具有存储在可执行文件中的值,我可以通过使用objdump
转储数据部分来读取vypis_ptr
中的内容
$objdump-d-j.数据vypis
vypis:文件格式elf64-x86-64
分解截面。数据:
0000000000600878 :
...
0000000000600880 :
...
0000000000600888 :
600888:d0 04 40 00….@。。。。。
0000000000600890 :
600890:a8 08 60 00 00。。。。。
在这里,我们可以看到值
4004d0
存储在vypis_ptr
中,但这正是vypis
的位置,如nm
的输出所示I删除了iostream
的冗余包含,以便您的源代码实际编译为C,并在我的系统上将其编译为可执行文件叫做vypis。以下是我的发现:
$nm vypis | fgrep vypis
0000000000 4004D0吨vypis
0000000000 600888 D vypis\u ptr
因此,vypis
,一个函数,在“文本”部分是一个全局函数,vypis\u ptr
,一个指向函数的指针,在“数据”部分是一个全局函数
数据部分中的对象具有存储在可执行文件中的值,我可以通过使用objdump
转储数据部分来读取vypis_ptr
中的内容
$objdump-d-j.数据vypis
vypis:文件格式elf64-x86-64
分解截面。数据:
0000000000600878 :
...
0000000000600880 :
...
0000000000600888 :
600888:d0 04 40 00….@。。。。。
0000000000600890 :
600890:a8 08 60 00 00。。。。。
在这里,我们可以看到值4004d0
存储在vypis_ptr
中,但这正是vypis
的位置,如nm
的输出所示。您确定编译器正在处理这些问题吗?main中没有任何内容,因此它无需执行任何操作,因此不需要包含任何有问题的代码。@PhilH,当然必须执行,vypis_ptr是一个外部可见的对象。这种地址解析不一定由编译器执行,而是由加载程序执行。唯一重要的事情是在程序启动前完成。而且,至少理论上,C和C++的这些东西是不同的。在C++中,这甚至可以是一个构造函数,它在程序启动后运行,但在它进入代码>主< <代码> >。@ JensGustedt将其作为答案,这是一个重要的部分。info@JensGustedtthx,把它作为答案贴出来,这样我就可以接受了。你确定编译器会为此烦恼吗?main中没有任何内容,因此它无需执行任何操作,因此不需要包含任何有问题的代码。@PhilH,当然必须执行,vypis_ptr是一个外部可见的对象。这种地址解析不一定由编译器执行,而是由加载程序执行。唯一重要的事情是在程序启动前完成。而且,至少理论上,C和C++的这些东西是不同的。在C++中,这甚至可以是一个构造函数,它在程序启动后运行,但在它进入代码>主< <代码> >。@ JensGustedt将其作为答案,这是一个重要的部分。info@JensGustedtthx,将其作为答案发布,所以我可以接受ithm,但为什么obj文件中有我的变量的名称?@Krab,因为它们是全局的,并且您使它们可见(通过没有将它们声明为static
),所以它们可以导出并在其他编译模块中使用。名称必须在那里,以便链接器可以找到符号。@Krab:-d
意味着不可禁用,此选项使用符号表中的信息来注释data section.hm输出中的地址。但是为什么obj文件中有my变量的名称?@Krab,因为它们是全局的,并且您使它们可见(通过没有将它们声明为static
)这样它们就可以被导出并在其他编译模块中使用。名称必须在那里,以便链接器可以找到符号。@Krab:-d
表示不允许使用,此选项使用符号表中的信息来注释数据段输出中的地址。