Tag: undefined behavior

是否使用未定义所有成员的结构未定义?

在块范围内考虑此代码: struct foo { unsigned char a; unsigned char b; } x, y; xa = 0; y = x; C [N1570] 6.3.2.1 2说“如果左值指定了一个自动存储持续时间的对象,该对象可以用寄存器存储类声明(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明)在使用之前没有对它进行任何分配),行为是不确定的。“ 尽管已为x的成员分配了值,但未执行对x赋值,并且未对其进行地址处理。 因此,看起来6.3.2.1 2告诉我们y = x中x的行为是未定义的。 但是,如果我们为x每个成员分配了一个值,那么考虑到为了6.3.2.1 2而未初始化x似乎是不合理的。 (1)严格来说,标准中是否有任何内容导致6.3.2.1 2不适用于(未定义)上述代码? (2)假设我们正在修改标准或确定对6.3.2.1的合理修改2,是否有理由偏好以下其中一项而不是其他? (a)6.3.2.1 2不适用于结构。 (b)如果一个结构的至少一个成员被赋予了一个值,则该结构在6.3.2.1的目的下不是未初始化的。(c)如果一个结构的所有已命名的1个成员都被赋予了一个值,那么该结构是为6.3.2.1的目的而未初始化2。 脚注 1结构可能具有未命名的成员,因此并不总是可以为结构的每个成员分配值。 (即使结构初始化,未命名的成员也具有不确定的值,每6.7.9 9.)

索引超过C数组的末尾

我在C中编写了一个简短的程序,只是为了看看当你索引数组末尾时会发生什么。 我发现它主要产生随机值(我知道它们实际上并不是随机的)直到一个点(在这种情况下52个索引超过结束),它每次产生0。 超过这一点的每个值和程序崩溃。 为什么是这样? 是程序结束分配内存空间? main() { int ar[4]; ar[0] = 99; ar[1] = 45; printf(“array: %d, %d random value: %d”, ar[0], ar[1], ar[55]); } 编辑:我还发现,如果我改变这个值总是最终为0(即ar [55] = 1000),那么程序的返回码就会增加。

C / C ++:这是未定义的行为吗? (2D数组)

如果我以下列方式浏览2D数组的元素,它是不确定的行为吗? int v[5][5], i; for (i = 0; i < 5*5; ++i) { v[i] = i; } 然后,它甚至编译? (我现在不能尝试,我不在家。)如果没有,那么想象我以某种方式获得了指向第一个元素并使用taht而不是v[i]的指针。

非初始化变量的默认值

我正在阅读有关调试的本教程 。 我在我的.c档案中粘贴了因子代码: #include int main() { int i, num, j; printf (“Enter the number: “); scanf (“%d”, &num ); for (i=1; i<num; i++) j=j*i; printf("The factorial of %d is %d\n",num,j); } 当我运行可执行文件时,它总是打印0 ,但是,教程的作者说它返回数字垃圾值。 我已经用Google搜索了这个,我读过这是正确的,除了静态变量。 所以它应该返回一个垃圾数而不是0 。 我认为这可能是由于不同版本的C,但指南是从2010年开始。 为什么我总是看到0而不是垃圾值?

为什么XOR与整数交换会触发警告?

我输入了以下程序: #include int main(void) { int a = 3; int b = 42; printf(“a = %d\nb = %d\n”, a, b); printf(“Exchanging values.\n”); a ^= b ^= a ^= b; printf(“a = %d\nb = %d\n”, a, b); return 0; } 没关系。 当我尝试编译它时,我得到了这个: $ gcc test.c -o test -Wall -Wextra -ansi -pedantic-errors test.c: In function ‘main’: test.c:11: […]

XOR交换算法中运算符的未定义行为?

void swap(int* a, int* b) { if (a != b) *a ^= *b ^= *a ^= *b; } 如上所述*a ^= *b ^= *a ^= *b只是*a = *a ^ (*b = *b ^ (*a = *a ^ *b))的快捷方式,可以(例如)第二个*a被评估(对于XOR)就在第三个*a被修改之前(由=)? 我是否用C99 / C11 / C ++ 98 / C ++ 11编写它是否重要?

修改数组中的一个元素而另一个线程修改同一数组的另一个元素时,它是定义良好的行为吗?

给定一个类型为foo_t[n]的数组和一组n个线程,其中n个线程中的每个线程都读取并修改数组的不同元素,我是否需要显式同步数组的修改,或者我可以假设同时修改成员数组是明确定义的行为? 它有多大foo_t /它的对齐方式有关系吗?

从堆栈地址形成指针范围是不确定的行为?

一些C或C ++程序员惊讶地发现即使存储无效指针也是未定义的行为 。 但是,对于堆或堆栈数组,可以存储一个超过数组末尾的地址,这允许您存储“结束”位置以便在循环中使用。 但是从单个堆栈变量形成指针范围是未定义的行为,如: char c = ‘X’; char* begin = &c; char* end = begin + 1; for (; begin != end; ++begin) { /* do something */ } 虽然上面的例子很没用,但是如果某个函数需要一个指针范围,并且你只有一个值来传递它,那么这可能很有用。 这是未定义的行为吗?

如果分配了该区域,那么访问超出其结尾的数组是不确定的行为?

可能重复: “struct hack”在技术上是不确定的行为吗? 通常访问超出其结尾的数组是C中未定义的行为。例如: int foo[1]; foo[5] = 1; //Undefined behavior 如果我知道数组末尾之后的内存区域是用malloc还是在堆栈上分配的话,它仍然是未定义的行为吗? 这是一个例子: #include #include typedef struct { int len; int data[1]; } MyStruct; int main(void) { MyStruct *foo = malloc(sizeof(MyStruct) + sizeof(int) * 10); foo->data[5] = 1; } 我已经看到在几个地方使用这个模式来制作一个可变长度的结构,它似乎在实践中起作用。 这是技术上未定义的行为吗?

2D数组索引 – 未定义的行为?

我最近遇到了一些代码,做了一些有问题的2D数组索引操作。 以下面的代码示例为例: int a[5][5]; a[0][20] = 3; a[-2][15] = 4; a[5][-3] = 5; 上面的索引操作是否受到未定义的行为的影响?