类型T的左值必须指向T类型对象吗?&*p是否要求p指向T类型对象?
C++中
&*p的类型关联与标准规则分析 给定ST *p,*p会产生左值(参考expr.unary.op#1);若静态类型ST为原生类型,将*p转换为右值时会实际访问并读取*p(参考conv.lval、basic.lval#11)。但在不将*p转换为右值的场景——比如计算&*p或为*p绑定引用时,p仍需指向动态类型DT的对象或函数,此时ST必须与DT存在关联吗?严格按字面规则推导,&*p似乎要求ST = DT,但这比实际访问的规则更严格,显然不合理。
expr.unary.op#1标准:一元
*运算符执行间接寻址,其操作数必须是指向对象或函数类型T的指针纯右值,运算符产生表示操作数指向的对象或函数的T类型左值。
由此引出核心问题:类型T的左值必须指向T类型的对象吗?显然并非如此,但标准是否有明确答案?
笔者预期&*p的限制应比访问*p更宽松,比仅计算p更严格,而以下两种场景的规则更为清晰:
两种明确场景的规则对比
- 指针访问(严格别名规则):实际访问时要求严格,仅当静态类型
ST属于特定类型列表时,操作才是定义行为。该列表包含的类型多于动态类型DT,具体包括DT及其有符号/无符号变体,以及char、unsigned char和std::byte(参考basic.lval#11)。 - 指针本身的计算:仅计算指针
p时,静态类型ST与动态类型DT无需关联。因为满足对齐要求时,从void*到任意类型的static_cast是定义行为(参考expr.static.cast#14)。
注:仅要求p指向对象或函数即可。
示例代码
#include <iostream> short* f(int *ip) { // 假设`ip`实际指向动态类型DT = int void *vp = ip; // 合法,参考conv.ptr#2 short* sp = static_cast<short*> (vp); // 合法,参考expr.static.cast#14 return &*sp; } int main(int argc, char ** argv) { int i = 0; short* sp = f(&i); void* vp = sp; int* ip = static_cast<int*>(vp); *ip = 1; std::cout << "I: " << i << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者Blaisorblade
相关产品推荐
相关产品推荐

