假设unsigned int没有陷阱表示,请执行下面标记为(A)和(B)的语句中的任何一个或两个引发未定义的行为,为什么或为什么不这样做,以及(特别是如果您认为其中一个定义明确但另一个不定义),您认为标准中存在缺陷吗?我主要对当前版本的C标准(即C2011)感兴趣,但如果在标准的旧版本或C++中有所不同,我也想知道这一点.
(_Alignas在这个程序中用于消除因对齐不充分而导致的任何UB问题.我在解释中讨论的规则虽然没有说明对齐.)
#include <stdlib.h>
#include <string.h>
int main(void)
{
unsigned int v1, v2;
unsigned char _Alignas(unsigned int) b1[sizeof(unsigned int)];
unsigned char *b2 = malloc(sizeof(unsigned int));
if (!b2) return 1;
memset(b1, 0x55, sizeof(unsigned int));
memset(b2, 0x55, sizeof(unsigned int));
v1 = *(unsigned int *)b1; /* (A) */
v2 = *(unsigned int *)b2; /* (B) */
return !(v1 == v2);
}
Run Code Online (Sandbox Code Playgroud)
我对C2011的解释是(A)引发未定义的行为,但(B)定义明确(存储未指定的值v2),因为:
memset被定义(§7.24.6.1)写入它的第一个参数作为-如果通过与字符类型,它被允许用于两左值b1和b2每特殊情况下,在§6.5p7的底部.
该对象b1具有声明的类型unsigned char[n].因此,它的有效访问类型也是unsigned char[n] …
在严格别名方面,这段代码是明确定义的行为吗?
_Bool* array = malloc(n);
memset(array, 0xFF, n);
_Bool x = array[0];
Run Code Online (Sandbox Code Playgroud)
有效类型的规则具有memcpy和memmove(C176.5§6)的特殊情况,但不适用于memset.
我认为有效的类型就变成了unsigned char.因为第二个参数memset需要转换为unsigned char(C17 7.24.6.1)并且由于有效类型的规则,(C176.5§6):
...或者被复制为字符类型数组,然后该访问的修改对象的有效类型以及不修改该值的后续访问是从中复制值的对象的有效类型,如果它有一个.
array后存储的数据的有效类型是memset什么?array[0]访问是否违反了严格的别名?因为_Bool不是严格别名规则中排除的类型(与字符类型不同).如何x指针指向的两个数据段?
我试过这个,基于stackoverflow上类似的解决方案,但输出不是我的预期.
这是代码:
void printXor(){
int j;
char* c = strdup("hey");
for(j = 0; j < strlen(c); j++){
c[j] ^= c[j];
}
printf("%d\n", *(int*)(c));
}
Run Code Online (Sandbox Code Playgroud)
但输出是:7955712.输出不应该是0吗?我对"嘿"感到"嘿",它在int中的值是0吗?