【发布时间】:2025-12-25 21:30:10
【问题描述】:
我正在尝试理解 6.5(p6) 中定义的严格别名规则:
如果一个值通过 lvalue 的类型不是字符类型,然后是 左值成为该访问的对象的有效类型 以及不修改存储值的后续访问。
和6.5(p7):
对象的存储值只能由左值访问 具有以下类型之一的表达式:88)
——与对象的有效类型兼容的类型
考虑以下示例:
struct test_internal_struct_t{
int a;
int b;
};
struct test_struct_t{
struct test_internal_struct_t tis;
};
int main(){
//alocated object, no declared type
struct test_struct_t *test_struct_ptr = malloc(sizeof(*test_struct_ptr));
//object designated by the lvalue has type int
test_struct_ptr->tis.a = 1;
//object designated by the lvalue has type int
test_struct_ptr->tis.b = 2;
//VIOLATION OF STRICT ALIASING RULE???
struct test_internal_struct_t tis = test_struct_ptr->tis;
return 0;
}
malloc(sizeof(*test_struct_ptr)) 没有声明类型,因为它已分配,如脚注 87:
87) 分配的对象没有声明类型
通过test_struct_ptr->tis.a 和test_struct_ptr->tis.b 访问的对象的有效类型为int。但是对象test_struct_ptr->tis自分配以来就没有有效类型。
问题:struct test_internal_struct_t tis = test_struct_ptr->tis; 是否违反了严格别名? test_struct_ptr->tis指定的对象没有有效类型,但lvalue有struct test_internal_struct_t类型。
【问题讨论】:
-
也许我遗漏了一些东西,但我在这里看不到任何别名。有一个副本,但这不是“别名”。
-
@4386427 是的,如果将
test_struct_ptr->tis分配给变量,则会发生复制。但让我感到困惑的是,没有涉及左值test_struct_ptr->tis的商店,但test_struct_ptr->tis.a和test_struct_ptr->tis.b是。所以test_struct_ptr->tis指定的对象没有有效类型(已分配),但左值本身有struct test_internal_struct_t类型。很可能我对这些部分的措辞理解有误... -
但是您确实分配给它......然后您将整个结构复制到 另一个 内存区域(具有自动存储持续时间)。这永远与别名无关。
-
@4386427:OP 的重点是他们存储一个
int和另一个int,然后读取struct test_internal_struct_t。那么分配的内存是如何产生struct test_internal_struct_t的有效类型的呢? -
@4386427:我以前遇到过这种区别,C 标准的一个缺点是它没有明确说明“通过左值”存储值的含义。
标签: c language-lawyer strict-aliasing