Lun*_*din 7 c strict-aliasing lvalue language-lawyer
假设我有一大块动态分配的数据:
void* allocate (size_t n)
{
void* foo = malloc(n);
...
return foo;
}
Run Code Online (Sandbox Code Playgroud)
我希望将指向的数据foo用作特殊类型type_t.但我想稍后这样做,而不是在分配期间.为了给分配的数据一个有效的类型,我可以这样做:
void* allocate (size_t n)
{
void* foo = malloc(n);
(void) *(type_t*)foo;
...
return foo
}
Run Code Online (Sandbox Code Playgroud)
根据C11 6.5/6,这个左值访问应该是有效的类型type_t:
对于没有声明类型的对象的所有其他访问,对象的有效类型只是用于访问的左值的类型.
但是,该行不(void) *(type_t*)foo;包含任何副作用,因此编译器应该可以自由地优化它,我不希望它生成任何实际的机器代码.
我的问题是:像上面这样的技巧安全吗?是否将数据作为副作用提供有效类型?或者通过优化代码,编译器是否也会优化掉有效类型的选择?
也就是说,使用上面的左值访问技巧,如果我现在调用上面这样的函数:
int* i = allocate(sizeof(int));
*i = something;
Run Code Online (Sandbox Code Playgroud)
这是否会导致严格的别名违规UB,或者现在是有效的类型int?
您明确引用的标准中的短语仅说明了对对象的访问.标准描述的对象的有效类型的唯一更改是之前的两个短语,它们清楚地描述了您必须使用要使其生效的类型存储到对象中.
6.5/6
如果通过具有非字符类型的左值的值将值存储到没有声明类型的对象中,则左值的类型将成为该访问的对象的有效类型以及不修改该值的后续访问的有效类型储值.