【发布时间】:2018-05-04 11:33:30
【问题描述】:
假设我有这个代码:
void foo() {
char s[10];
char v1 = s[0]; // UB
char v2 = s[10]; // also UB
}
void bar() {
char s[10];
strcpy(s, "foo");
char v3 = s[3]; // v3 is zero
char v4 = s[0]; // v4 is 'f'
char v5 = s[4]; // What?
}
由于s[0] 到s[3] 的地址在strcpy 中被访问,并且s[0] 到s[9] 在连续内存中,我想整个数组应该包含一些值(包括不确定)。
关于v5的操作是否定义明确?或者v5 只是一个不确定的值(不会触发任何 UB)?
如果数组是 int 类型并且仍然部分赋值怎么办?
【问题讨论】:
-
@Lanting:C 问题不会重复 C++ 问题。不同语言的规则不同,答案必须针对每种语言,除非是专门询问两种语言的共同点。
-
@Stargateur:我相信字符类型可能有陷阱表示,
unsigned char除外。但是,C 2011 段落说读取具有陷阱表示的对象是未定义的行为,6.2.6.1 5,特别排除了字符类型。因此,读取具有陷阱表示的字符并不是未定义的。 -
@iBug: (a) C 标准中对字符类型的处理方式不同。如果您使用
int的数组,这个问题的答案会有所不同。 (b) 你的前提是有缺陷的。char v1 = s[0];没有未定义的行为。 -
如果可以使用
register存储类声明访问未初始化的对象,则它是未定义的。问题是,这如何转化为数组?似乎数组可以用register声明,但 J2 附录说将寄存器分类数组转换为其第一个成员是 UB,但这种转换是定义索引的方式,所以看起来寄存器声明的数组是 un-可索引,但由于您正在索引,因此无法将数组声明为寄存器,因此取消引用应产生未指定的值但不会导致 UB。不过,这很奇怪。
标签: c arrays language-lawyer undefined-behavior