Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 链接器在将指针变量链接到C++;?_C++ - Fatal编程技术网

C++ 链接器在将指针变量链接到C++;?

C++ 链接器在将指针变量链接到C++;?,c++,C++,我已经搜索了很多关于外部数组指针的问题,但仍然感到困惑 在以下代码中: // example 1 //1.cpp int a[]={1,2,3}; //the array a //main.cpp extern int*a; //the pointer a 在main.cpp中,当我使用printf打印a时,它会给出1,它是1.cpp中定义的数组a的前四个字节。打印&a会得到0x1234(例如),这是1.cpp中定义的数组a的第一个元素的地址 它的作用类似于指针a通过地址0x1234强

我已经搜索了很多关于外部数组指针的问题,但仍然感到困惑

在以下代码中:

// example 1
//1.cpp
int a[]={1,2,3};  //the array a

//main.cpp
extern int*a;  //the pointer a

main.cpp
中,当我使用
printf
打印
a
时,它会给出
1
,它是
1.cpp
中定义的数组
a
的前四个字节。打印
&a
会得到
0x1234
(例如),这是
1.cpp
中定义的数组
a
的第一个元素的地址

它的作用类似于指针
a
通过地址
0x1234
强制连接到数组
a
。因此,指针
a
的值位于
0x1234
,即
1
,因为
sizeof(int*)==sizeof(int)
为32位。

我了解到链接器需要未解析符号表和导出符号表来将声明链接到定义

编译
1.cpp
时,符号
a
添加到导出符号表中,编译
main.cpp
时,符号
a
添加到未解析符号表中。由于它们的类型不同,因此应以不同的方式命名

实际上,链接器可以检查变量的类型,因为:

//example 2
//1.cpp
int a[]={1,2,3}

//2.cpp
extern char *a;
抛出一个链接错误,
char*a
未解决,但它们没有强制混合,链接器可以捕获错误。
在单个单元中:

//example 3
int a[] = {1,2,3};
int *ptr = a; 
编译器隐式地将
a
变量转换为临时
int*
,但在不同的单元中不能这样做

那么为什么链接器没有捕获接收数组的外部指针呢。链接器实际上做什么


非常感谢你

> P> > C/C++部分可以立即处理:在许多实现中,C不强> Mangle < /强>任何符号,因为它们都是唯一的,并且缺少变量的超载,C++也不会使它们变粗。(变量模板被破坏,静态数据成员也被破坏。)这不是该语言的要求:在形式上,必须对变量使用
extern“C”
,但该标准允许与未注释的全局变量发生冲突,这在实践中经常发生(现在是向后兼容的一个点。其余的C和C++是相同的。
典型的链接器管理的是每个变量的地址,没有类型信息,只包含在损坏的名称中。数组的地址是其第一个元素的地址,因此您的“指针”最终成为该元素的别名(类型错误)。(正如评论中所指出的,由于这是一种格式不正确的情况,其他的欢闹可能会接踵而至,比如通过指针的存储在数组中不可见(通过其他指针访问)。)不同的链接器实现可能会更有帮助,但向后兼容性同样禁止它。

我认为不允许您这样做,因此,这取决于链接器。您的示例包含一个单定义规则(ODR)冲突。它们的格式不正确,不需要诊断。@chris I使用VS2017和g++8.1编译和链接,它们是相同的结果。@Igor示例2可能包含。应该有<代码>外部字符*<代码>,抱歉。@ @库川,很多不被允许的东西仍然会编译甚至运行。一些C++编译器(例如VisualStudio)会对变量名进行修改。这使得链接器可以在问题的第二个示例中检测到错误。@anatolyg:是的,我稍微软化了语言以解释这一点,但显然不是这种情况引发了这个问题。@Davidsherring我用g++8.1尝试了第二个示例,没有链接错误,这意味着符号的类型信息在链接时会丢失。那么,这是VS2017和g++实现链接器的一个不同方面吗?@sakugawa:这是ABI的一个方面。一些编译器使用安腾ABI,它具有这种行为。