C/C++ Undefined Behaviour (UB)

C++/C 程序未定义行为 实例

除零

int main()
{
    int x = 25, y = 0;
    int z = x / y;
    printf("Hello World!");
    return 0;
}

变量未初始化

int main()
{
    bool val;
    if (val)
        printf("TRUE");
    else
        printf("FALSE");
}

访问空指针NULL

int main()
{
   int *ptr = NULL;
   printf("%d", *ptr);
   return 0;
}

访问越界

int main()
{
   int arr[5];

   // We access arr[5] in last iteration.
   for (int i=0; i<=5; i++)
      printf("%d ", arr[i]);
}

有符号int的溢出

int main()
{
   int x = INT_MAX;
   printf("%d", x+1);
   return 0;
}

试图更改字符串字面值

int main()
{
   char *s = "geeksforgeeks";
   s[0] = 'e';
   return 0;
}

在一个序列操作值未确定的情况下对一个变量多次更改

#include 
int main()
{
   int i = 8;
   int p = i++*i++;
   printf("%d\n", p);
}

以上这些程序的输出都是不可预测的,也就是未定义的。C/C++标准编译器对这些文定义的行为可以做任何事情。像java这样的语言往往会在发现问题时立即解决,凡是对于C/C++在某些情况下可能会继续执行程序即便代码存在错误,因此会导致不可预测的结果。程序可能会以任意类型的错误而崩溃crash。

了解未定义行为的重要性

不了解C/C++的UB行为,可能会因此给后续使用者带来大量的问题,而难以debug发现。

未定义行为的风险和缺点

程序员有的时候会依赖于某个特定的编译器对undefined behaviour的实现,但是这样是很不好的!因为当编译器升级或者更换编译器后都会带来新的问题。另一方面,UB也会带来程序的安全缺陷,比如数组访问的越界问题,可能会导致缓冲区溢出攻击。

未定义行为存在的优点

因为UB的存在,编译器不需要做过多的范围检查,以此可以带来极大效率提升。除此之外还有一些其他的优点。

你可能感兴趣的:(C++)