此代码片段是否违反严格别名规则:
int main()
{
short tab[] = {1,2,3,4};
int* ps = (int*)(&tab[0]);
int i = *ps;
}
我知道,如果这是违反相反的行为,那将是违规行为
int main()
{
int tab[] = {1,2,3,4};
short* ps = (short*)(&tab[0]);
short s = *ps;
}
答案 0 :(得分:2)
指向另一个(任意)指针类型的指针,只要它不是格式错误,不构成违规;但是在取消引用该指针后访问pointees值将是。
你的演员阵容相当于reinterpret_cast
,[expr.reinterpret.cast] / 7:
可以将对象指针显式转换为对象指针 不同的类型。当“指向
T1
的指针”类型的prvalue v时 转换为“指向 cvT2
的指针”,结果为static_cast<
cv 如果T2*>(static_cast<
和void*>(v))
都是标准布局,则T1
cvT2
类型(3.9)和T2
的对齐要求并不比。{更严格 那些T1
,或者任何一种类型都是无效的。
答案 1 :(得分:2)
当然违反了严格的别名。代码通过不同类型的指针访问值,并且它不是char*
。
int main()
{
short tab[] = {1,2,3,4};
int* ps = (int*)(&tab[0]);
*ps = 3;
if(tab[0] == 1) return 1;
return 0;
}
允许代码在那里返回1。因为写入* ps是对int
的写入,并且根据严格的别名规则,int
指针不可能指向short
。因此,允许优化器看到tab
数组未被修改,优化if
语句,因为它总是为真,并重写整个函数只返回1.
答案 2 :(得分:0)
如果您尝试取消引用转换后的指针,则在两种情况下都会得到未定义的行为。
非正式地说,这是因为类型的对齐方式可能不同。
使用联盟;较长的类型和较短类型的数组是一种安全的数据转换方式。