Clarification:我的问题是:
int
类型的lvalue来访问有效类型const int
的对象?这个问题有两个代码示例,它们使用int
类型的lvalue来访问有效类型const int
的对象,我的目的是在尽可能少的分散注意力的情况下实现这一点。如果有任何UB的其他来源,除了这个特定的问题,请留下评论,我将尝试更新代码样例。
下面是一个供讨论的特定代码示例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
const int c = 5;
printf("%d\n", *(int *)&c);
}
我认为可能是UB的原因是严格的别名规则似乎表明它是UB:
C11 6.5/7 对象的存储值只能由具有下列类型之一的lvalue表达式访问:
这个对象的有效类型(6.5/6)是const int
。
第一点:int
和const int
是不兼容的类型(6.2.7/1,6.7.3/10)。
第二个要点:int
似乎不是const int
的合格版本,因为我们没有通过添加限定符来生成它。但是,不清楚6.2.5/26:
每种非限定类型都有其类型的几个限定版本,对应于const、volatile限定符的一个、两个或全部三个的组合。类型的限定或非限定版本是属于同一类型类别的不同类型,并且具有相同的表示形式和对齐要求。派生类型不受派生类型的限定符(如果有的话)限定。
它没有定义什么是“const int
的合格版本”,它只定义了应用于不限定类型时的“限定版本”一词。
第二个代码示例:
int *pc = malloc(sizeof *pc);
memcpy(pc, &c, sizeof c);
printf("%d\n", *pc); // UB?
由于memcpy
保留了有效类型(6.5/6),所以通过*pc
读取与严格的混叠规则的交互与第一个示例中通过*(int *)&c
读取的操作完全相同。
发布于 2015-02-17 18:53:01
事实并非如此。你所发现的是为什么它不能含蓄地投射。
6.2.5/26指出:
每种非限定类型都有其类型的几个限定版本,对应于const、volatile限定符的一个、两个或全部三个的组合。类型的限定或非限定版本是属于同一类型类别的不同类型,并且具有相同的表示形式和对齐要求。
(注:每个不合格的类型。const int
不是不合格的,但int
是不合格的。
附脚注:
相同的表示和对齐要求意味着与函数的参数、函数返回值和联合成员之间的互换性。
这意味着读取它将以相同的方式工作,并产生相同的值。
6.7.3/6只对修改规定了UB:
如果试图通过使用具有非const限定类型的lvalue来修改使用const限定类型定义的对象,则该行为是未定义的。
https://stackoverflow.com/questions/28574542
复制相似问题