constexpr变量的唯一地址 [英] Unique address for constexpr variable

查看:150
本文介绍了constexpr变量的唯一地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以为constexpr变量分配一个唯一的地址,即对于变量可用的所有翻译单元(通常是通过标头)都是一样的?请考虑以下示例:

Is it possible to have a unique address allocated for a constexpr variable, i.e. the same for all translation units where the variable is available (usually through a header)? Consider the following example:

// 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 ,我得到一个链接器错误重复符号_foo在:ao和bo 我发现有点奇怪,因为我认为添加 extern 更有可能导致编译器从另一个对象导入该符号,而不是从当前对象导出它。但是,我似乎对这里的工作原理的理解是错误的。

Compiling a.cc and b.cc separately, and linking them together using gcc 4.7, I see two different addresses printed. If I add the keyword extern in the header, I get a linker error duplicate symbol _foo in: a.o and b.o which I find kind of surprising, because I thought that adding extern would more likely cause the compiler to import that symbol from another object instead of exporting it from the current object. But it seems my understanding of how things work was wrong here.

有一个合理的方法在一个标题中声明一个constexpr,可以在它们的常量表达式中使用它,并且使得所有翻译单元都符合该符号的地址?我希望一些额外的代码表示该符号实际属于的单个翻译单元, code> extern 和非 - extern 变量,不含 constexpr

Is there a reasonable way to have a constexpr declared in one header, such that all translation units can use it in their constant expressions, and such that all translation units agree as to the address of that symbol? I would expect some additional code to denote the single translation unit where this symbol actually belongs to, just like with extern and non-extern variables without constexpr.

推荐答案

如果需要获取constexpr变量的地址,请将其声明为静态成员变量。它可以用这种方式作为常量表达式(而不是使用返回一个常量的函数)。

If you need to take the address of constexpr variable, declare it as a static member variable. It can be used as a constant expression this way (as opposed to using a function returning a const).

foo.hpp:

#ifndef FOO_HPP
#define FOO_HPP

struct Foo {
  static constexpr int foo { 42 }; // declaration
};

#endif // FOO_HPP

foo.cpp:

#include "foo.hpp"

constexpr int Foo::foo; // definition

bar.cpp:

#include "foo.hpp"

const int* foo_addr() {
  return &Foo::foo;
}

int foo_val() {
  return Foo::foo;
}

main.cpp:

#include <iostream>
#include "foo.hpp"

extern const int* foo_addr();
extern int foo_val();

constexpr int arr[Foo::foo] {}; // foo used as constant expression

int main() {
  std::cout << foo_addr() << " = " << foo_val() << std::endl;
  std::cout << &Foo::foo << " = " << Foo::foo << std::endl;
}

输出:

$ g++ -std=c++11 foo.cpp bar.cpp main.cpp -o test && ./test
0x400a44 = 42
0x400a44 = 42

这篇关于constexpr变量的唯一地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆