我什么时候可以确定一个 constexpr 全局变量会像 C 宏一样被"forgotten"?
When can I be sure a constexpr global variable will be "forgotten", like a C macro?
我想使用全局constexpr
变量:
constexpr int foo = 123;
而不是 C 宏:
#define FOO (123)
在我正在编写的某些代码中。我希望得到相同的行为保证,从某种意义上说,这不会在运行时占用内存空间,也不会在编译的目标代码中可见/存在(也就是说,它的值将用作相关的即时值(。
我能得到这个保证吗?在某些条件下?当然,假设我没有试图使用x的地址或任何此类有趣的业务。
C++ 标准不保证在运行时占用内存空间或目标文件的内容。
命名空间范围的constexpr int foo = 123;
意味着foo
具有内部链接,并且在此行可见的每个翻译单元中,都有一个静态存储持续时间为 sizeof(int)
字节的对象。
如果程序的输出不依赖于存储是否实际存在,则允许(但不是必需(编译器优化此存储。 (这称为假设规则(。
存储可能不会优化的一个例子是,如果你有一个函数:
int const *bar() { return &foo; }
在实践中:
- 如果
foo
不是ODR使用的,那么它很可能在运行时不会占用内存。 foo
的名称很可能不会出现在目标文件中,因为它具有内部链接。
我能得到这个保证吗?在某些条件下?假设, 当然,我不想使用x的地址或任何此类有趣的业务。
是的,编译器几乎总是在编译时用foo
替换数字,没有额外的内存 请参阅constexpr
。几乎可以肯定的是,编译器只会在获取foo
地址时为其分配内存。
而且,从链接([expr.const](...我们看到一个注释:
注: 常量表达式可以在翻译过程中计算。
而且,据我所知C++大多数编译器而言,他们会在可能的情况下计算和折叠表达式。
使用 gcc.godbolt.org,此代码(不采用foo
的地址(...
constexpr int foo = 123;
int x(){
int b = 5 + foo;
return b;
}
如果没有优化标志,生成的代码为:
x():
movl $128, %eax
ret
====
=======================================但是这个代码...(以foo
地址为准(
constexpr int foo = 123;
int x(){
int b = 5 + reinterpret_cast<long>(&foo);
return b;
}
生成。。。。
x():
movq foo, -8(%rsp)
movl foo, %eax
addl $5, %eax
ret
foo:
.long 123
注意:为什么我使用可能而不是如果意志是因为C++标准不会强迫编译器这样做,(但他们几乎肯定会这样做,有些人可以自由地不这样做他们的特定约束(。
我希望得到相同的行为保证,从某种意义上说,这不会在运行时占用内存空间,也不会在编译的目标代码中可见/存在(也就是说,它的值将用作相关的即时值(。
constexpr int foo = 123;
每当编译器点击它时,将同样被视为123
。没有额外的记忆,没有什么花哨的。
所以是的,它完全等同于预处理器的替代品
#define FOO (123)
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- 堆栈和队列是否像C++中的数组一样传递?
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 我们可以将集合的值存储在变量中吗?就像我们可以将数组的值存储在变量中一样
- 我如何在C++像在 Python 中一样实现 f 字符串?
- 自制的上衣:看起来一样,但不完全相同
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 像 CPP 中的控制台一样的应用程序
- 为什么C++中没有常量引用,就像常量指针一样?
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- 有没有像给定的一样的 std::optional_function
- Java 是否像C++模板一样具有泛型推论?
- 记忆栅栏和记忆屏障是一样的吗
- 对象作为参数传递,就好像我们正在传递构造函数值一样
- 像自定义类一样构造的指针(内置类型)如何工作?
- 我什么时候可以确定一个 constexpr 全局变量会像 C 宏一样被"forgotten"?