📜  C C ++中带有示例的未指定行为(1)

📅  最后修改于: 2023-12-03 14:39:36.843000             🧑  作者: Mango

C/C++中带有示例的未指定行为

在C/C++中,有些操作的行为是未指定的,这意味着标准没有规定具体的行为,也没有保证编译器、操作系统或硬件会有一致的行为。这些未指定行为可能会导致程序出现意外结果,因此在编写代码时需要注意这些情况。

下面列举了一些常见的未指定行为和相应的示例:

1. 空指针的引用和解引用行为

对空指针进行解引用操作或者引用空指针,是未指定行为。这会导致不可预测的结果,例如崩溃或者不可预测的输出。

int *ptr = nullptr;
*ptr = 10; // 操作未指定,会导致不可预判的结果
int val = *ptr; // 同上

2. 函数参数表达式求值的顺序

对于函数调用中传递的参数,编译器可能按任意顺序求值。因此,在函数调用中使用表达式的多个参数可能会导致意外结果。

int a = 0, b = 0;
int func(int x, int y) {
    return x + y;
}
int val = func(++a, ++b); // 操作结果未指定,可能得到3也可能得到4

3. 带有副作用的表达式顺序

在带有副作用的表达式中,编译器未指定表达式的求值顺序。这可能会导致任意数量的未定义行为。

int a = 0, b = 0;
int func(int x) {
    ++x;
    return x;
}
int val = ++a + func(b++); // 操作结果未指定,可能得到2也可能得到3

4. 数组越界行为

访问数组越界是未定义的行为。这可能导致程序崩溃、数据损坏或其他不可预测的结果。

int arr[2] = {1, 2};
int val = arr[2]; // 访问越界,结果未定义

5. signed整数上的移位行为

在signed整数上进行移位运算是未指定的行为。这可能导致未知的结果。

int val = -1;
val = val >> 1; // 移位结果未指定

最好的方法就是避免使用未指定行为的代码,如果确实需要使用,则需要理解其行为并谨慎使用。