【发布时间】:2020-01-17 20:14:24
【问题描述】:
刚刚花了一段时间调试一个多重定义错误,但我不清楚为什么会发生这种行为并希望了解。
我在头文件中有类似的内容。
//foo.h
#pragma once
my_states States[N] = {...};
后来,bar.h 包含了foo.h,因为bar.cpp 具有需要了解my_states 的功能。
当我为bar 编写单元测试并将bar.h 包含在test.cpp 中时,问题就出现了。
bar.o: multiple definition of MyNamespace::named_states
test.o: first defined here
我已通过更改为
解决了这个问题constexpr my_states States[n] = {...}; 在foo.h。
但是我不明白为什么这解决了这个问题。我知道我对符号 my_states 有多个定义,这使链接器感到困惑,但是如果我有我的 #pragma once 保护,为什么要多次定义它?我不确定为什么我需要 constexpr 限定符来表示这应该只有 1 个定义,而据我所知 #pragma once 应该阻止编译器首先尝试创建多个定义。
【问题讨论】:
-
pragma 一旦阻止为 one 编译单元重新包含相同的头文件,它就不能跨编译单元工作。
-
这应该分成 2 个独立的问题 - 一个是关于为什么 constexpr 解决了这个问题,一个是关于为什么
#pragma once没有。