提问人:Akshay J R 提问时间:11/1/2023 最后编辑:Akshay J R 更新时间:11/1/2023 访问量:129
constexpr 指针如何存在并且 constevel 函数在编译时返回指针?
How can constexpr pointers exist and constevel function return a pointer at compile time?
问:
我正在浏览 constexpr 和 consteval 的主题,并发现了以下内容,
- 我们可以有 CONSTEXPR 类型的指针
- CONSTEVAL 函数可以返回 CONSTEXPR 变量的指针
我在这里的问题是,上述 2 怎么可能?
以上 2 个问题是因为,据我所知,所有变量都是在运行时在内存中创建的,指针是该内存的地址。
那么,CONSTEXPR 类型的指针是如何存在的(因为 CONSTEXPR 变量必须在编译时初始化)?以及 CONSTEVAL 函数如何在编译时返回 CONSTEXPR 变量的指针?
#include <iostream>
constexpr int a{1};
consteval const int* aptrfunc() //How can this function return a pointer at compile time
{
return &a;
}
int main()
{
constexpr const int* aptr{&a}; //How can this exist at compiletime?
std::cout<<aptr<<'\n'; //Prints address of a
std::cout<<aptrfunc()<<'\n'; //Prints address of a
return 0;
}
答:
以上 2 个问题是因为,据我所知,所有变量都是在运行时在内存中创建的
是的,但并非所有人都有固定地址。
就标准而言,允许 constexpr 指针指向保持在固定地址的对象。在任何函数(全局对象)之外定义的对象都有一个固定的地址,因此它的地址可以用来初始化 constexpr 指针。
就像你的例子一样,是一个全局的,因此保持在固定地址,所以可以制作一个 constexpr 指针来指向它。a
int
实现/编译器可能会以符号方式处理此类 (constexpr) 指针,但这是实现细节。
指针是该内存的地址
嗯,不完全是。cppreference.com 使用的措辞是“代表地址”。指针允许程序访问它所指向的内容比指针具有特定值或位模式更重要。你越来越想知道某个价值。
如果你抽象地思考,你可以用指针做很多事情,而不知道确切的地址。例如,您可以确定两个指针是否指向同一地址。您可能不知道确切的地址,只知道它们是相同的。在实践中,对值有效的地址在编译时是已知的,直到操作系统在运行时提供的偏移量,并且在整个执行过程中是固定的。这足以确定两个指针是否相等。同样,在需要常量表达式的地方,“最多一个偏移量”足以让编译器执行它需要执行的操作。constexpr
有趣的是,不需要常量表达式的一个地方是流式处理运营商的操作数。也就是说,在表达式中,不需要编译器能够准确确定将显示哪些字符。相反,可以在运行时确定输出字符。在这方面,在程序执行之前无法查看 的值。但是,在编译时,尽管无法显示确切的值,但已知表达式表示 的地址,这对于所有(合法的)编译时处理来说已经足够了。std::cout<<aptr
aptr
aptr
a
评论
extern
inline
constexpr
constexpr
static_assert(aptr != aptrfunc());
a
a
评论
constexpr
-ness 不是类型的一部分,它是变量(或函数或其他东西)的单独属性。constexpr
constexpr
static
costexper
.data