的extern const的链接说明被看似由G忽略++(extern const linkage s

2019-09-30 05:53发布

我有一个情况建设有一个C ++编译器是C代码库,平行这样的:

lib.h

extern int const values[2] = {1, 2};

lib.c

#include "lib.h"

main.c中

#include <iostream>

extern int const values[2];

int main() {
    std::cout << values[0] << ":" << values[1] << std::endl;
}

我不得不添加的,因为东西在指出的extern C ++ 03标准附录C兼容性C.1.2条款3 。 (编译与-fpermissive将席卷这个的地毯下。)

顺便说一下它使怎么区别values出现在objdump的是这样的前extern

$ objdump -t lib.o | grep values
0000000000000000 l     O .rodata    0000000000000008 _ZL6values

$ objdump -t main.o | grep values
0000000000000000         *UND*  0000000000000000 values

......然后是这样的添加后:

$ objdump -t lib.o | grep values
0000000000000000 g     O .rodata    0000000000000008 values

$ objdump -t main.o | grep values
0000000000000000         *UND*  0000000000000000 values

所以名字改编被放弃了,我们会看到一个“L”变成“G”,和链接器不会抱怨values是不确定的。


现在想象有两个非常相似的文件,以同样的方式修改相同的情况:

TMP-exttypes.h

extern const REBYTE Reb_To_RXT[REB_MAX] = { /* bunch of stuff */ };

A-lib.c

extern const REBYTE Reb_To_RXT[REB_MAX];

这些项目只有两个Reb_To_RXT定义,建立清洁。 但它没有链接,当我objdump的仅有的两个文件提到它我得到:

$ objdump -t a-lib.o | grep Reb_To_RXT
00000000         *UND*  00000000 Reb_To_RXT

$ objdump -t f-extension.o | grep Reb_To_RXT
00000080 l     O .rodata    00000038 _ZL10Reb_To_RXT

它说,L,和它的名字错位。 这并没有做出非常简单的例子高兴。 但我想知道这是怎么用的每一次亮相就可以了EXTERN发生。 我说得对不对相信这是一个冒烟的枪... ...,并且一般不应该发生的,只有声明为extern的东西不应该有本地联动,地方?

Answer 1:

我不能让你什么的感觉。

但...

extern int const values[2] = {1, 2};

在头文件,你有UB如果这头被包含在一个以上的翻译单元。 最有可能的,但不一定然后你会得到一个链接错误。

一个解决方案:声明阵列中的报头,如

extern int const values[2];

但在执行文件(初始化)定义它。

另一种解决方案是使用模板特技或内联函数技巧可以定义在头文件阵列。

内联函数绝招:

typedef int const Values[2];

inline Values& valuesRef()
{
    static Values   theValues = {1, 2};
    return theValues;
}

static Values& values = valuesRef();


Answer 2:

是,对的。

你(我)正在编辑的文件是自动生成的,并通过一个干净的化妆,这是人注目的一半写下的思维过程实际上破坏。 这“TMP”你在那个特定的头看应该向提示“暂时的,不编辑”,如果文件没有在编辑器中重新载入你使用它可能会造成混淆。

(补完的思路反正机构知识。:-P)



文章来源: extern const linkage specification being seemingly ignored by G++