外部常量链接规范似乎被G++忽略了
extern const linkage specification being seemingly ignored by G++
我遇到了一种情况,用一个与之类似的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_XT定义,构建得很干净。但它没有链接,当我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 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();
是,正确。
你(我)正在编辑的文件是自动生成的,实际上是由一个干净的make销毁的,在写下思考过程的中途注意到了这一点。你在那个特定的标题中看到的"tmp"应该暗示"临时的,不要编辑",如果文件没有在你使用的编辑器中重新加载,这可能会让人困惑。
(完成了机构知识的思路。:-p)
- 为什么在全局范围内使用"extern int a"似乎不行?
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 类的C++属性似乎已重新初始化
- 我似乎对if/else的基本语句有问题:/
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 向量范数的c++中的||运算符
- 为什么是谷神星协方差.计算()似乎永远运行而不返回?
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 读取某些文件时出现分段错误,似乎与文件大小无关
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- 当我使用自定义类型创建动态数组时,即使使用字符串,它似乎也不起作用
- CMake 错误"源似乎不包含 CMakeLists.txt",路径/库连接问题
- 我似乎无法为指针分配一个数组,然后更改数组的内容
- 工会成员的析构函数似乎是自动调用的
- 我似乎无法修改帧缓冲
- 为什么我的全局变量似乎没有变化?
- 插入一个基本的单向链表节点似乎破坏了我的 c++ 代码?
- getline 函数似乎在 C++ 中不起作用
- C++中的无穷范数函数
- 我似乎无法让 msvc 链接器在 vscode 上正常工作