是否可以为constexpr变量分配一个唯一地址,即对于变量可用的所有翻译单元(通常是通过标头)是否都是相同的?考虑下面的例子:constexpr变量的唯一地址
// foo.hh
#include <iostream>
constexpr int foo = 42;
// a.cc
#include "foo.hh"
void a(void) { std::cout << "a: " << &foo << std::endl; }
// b.cc
#include "foo.hh"
extern void a(void);
int main(int argc, char** argv) {
a();
std::cout << "b: " << &foo << std::endl;
}
编译a.cc
b.cc
和分开,并使用gcc 4.7连接在一起,我看到印刷两个不同的地址。如果我在标题中添加了关键字extern
,我得到了一个链接器错误duplicate symbol _foo in: a.o and b.o
,我觉得有点令人惊讶,因为我认为添加extern
会更有可能导致编译器从另一个对象导入该符号,而不是从当前对象中导出该符号。但似乎我对事物如何运作的理解在这里是错误的。
是否有合理的方法在一个头文件中声明constexpr,以便所有的翻译单元都可以在其常量表达式中使用它,并且所有翻译单元都同意该符号的地址?我希望一些额外的代码来表示这个符号实际上属于的单个翻译单元,就像extern
和非extern
变量没有constexpr
一样。
我相信你'foo'具有内在联系,所以你看到两个单独的副本。解决问题的常用方法是在头文件中声明'extern const int foo',并在* one *翻译单元中将其实现为'const int foo = 42;'。但是它可能显然不是一个常量表达式,因为'int a [foo]'需要在编译时解析,而不仅仅是在链接时。 – 2013-02-14 10:13:29
也许还有另一种方法来实现你想要做的事情。那么......你想用这个地址做什么? – 2013-02-14 10:49:09
@NicolBolas:到目前为止,我一直试图去处理'constexpr'。我习惯于对'const'全局变量使用外部链接,以避免重复的内存分配,即使有人决定采用这种野兽的地址。现在用'constexpr'这个似乎不再可能了。所以我实际上试图找出的是,即使我现在无法想象的一些奇怪的代码决定将这些东西的地址都放在这个地方,是否有办法避免数据重复。 – MvG 2013-02-14 11:06:03