constexpr指针用constexpr int变量初始化报错,加static正常的原因解析
问题描述
我编写的C++代码如下:
int main() { constexpr int i = 5; constexpr const int *p = &i; return 0; }
使用以下命令编译:
g++ main.cpp
出现编译错误:
main.cpp: In function ‘int main()’:
main.cpp:3:28: error: ‘& i’ is not a constant expression
3 | constexpr const int *p = &i;
| ^~
我的g++版本信息:
Target: x86_64-pc-linux-gnu Configured with: /build/gcc/src/gcc/configure --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 12.2.0 (GCC)
按照提示给变量i添加static关键字后代码可正常编译,但我不理解其中的原因,希望得到解释。
原因解释
核心逻辑在于C++标准对constexpr初始化表达式的规则限制:
- 未加
static的普通局部变量属于自动存储期,它的内存地址是程序运行时分配到栈上的临时地址,每次进入函数都会重新分配,无法在编译阶段确定固定值。而constexpr要求初始化值必须是编译期可计算的常量表达式,因此&i不满足要求,编译器报错。 - 加上
static后,变量变为静态存储期,它的内存地址在编译链接阶段就已确定(分配到全局/静态存储区),此时&i是编译期可确定的常量表达式,完全符合constexpr指针的初始化条件,因此编译通过。
简单总结:static将局部变量的地址从「运行时动态确定」转为「编译时固定确定」,满足了constexpr对初始化表达式的编译期常量要求。
内容的提问来源于stack exchange,提问作者Thai Nguyen
相关产品推荐
相关产品推荐

