C 和 C++ 中的未定义行为

简介: 考虑以下 C/C++ 程序并尝试猜测输出?

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战


考虑以下 C/C++ 程序并尝试猜测输出?


程序 1(除以 0)


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

程序2(未初始化的变量)


int main()
{
  bool val;
  if (val)
    printf("TRUE");
  else
    printf("FALSE");
}
复制代码

程序3(访问NULL指针的值)


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

程序4(越界访问)


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

程序5(超出signed int的限制)


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

程序 6(尝试修改字符串文字)


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

程序7(在定义的序列点之前多次修改变量)


#include <stdio.h>
int main()
{
int i = 8;
int p = i++*i++;
printf("%d\n", p);
}
复制代码


以上所有程序的输出都是不可预测的(或未定义的)。编译器(实现 C/C++ 标准)可以自由地做任何事情,因为这些是 C 和 C++ 标准未定义的。


像 Java 这样的语言会在发现错误后立即捕获错误,但在少数情况下,像 C 和 C++ 这样的语言会继续以一种无声但错误的方式执行代码,这可能会导致不可预测的结果。该程序可能会因任何类型的错误消息而崩溃,或者它可能会在不知不觉中损坏数据,这是一个需要处理的严重问题。


了解未定义行为的重要性


如果用户开始在 C/C++ 环境中学习并且不清楚未定义行为的概念,那么这可能会在未来带来很多问题,比如调试其他人的代码实际上可能很难追踪未定义错误的根源。


未定义行为


风险和缺点


程序员有时依赖于未定义行为的特定实现(或编译器),这可能会在编译器更改/升级时导致问题。例如,在大多数编译器中,最后一个程序生成 72 作为输出,但是基于此假设实现软件并不是一个好主意。


未定义的行为也可能导致安全漏洞,特别是由于未检查数组越界(导致缓冲区溢出攻击)的情况。


未定义行为的优点


C 和 C++ 具有未定义行为,因为它允许编译器避免大量检查。假设一组具有更高性能数组的代码不需要查看边界,这避免了复杂的优化传递来检查循环外的此类条件的需要。当程序获得有符号溢出的未定义性质(通常由 C 编译器提供)的优势时,紧密绑定的循环会将程序从 30% 加速到 50%。


我们还有另一个优点,因为它允许我们将变量的值存储在处理器寄存器中,并随着时间的推移对其进行操作,该值大于源代码中的变量。它还有助于环绕然后编译时检查,如果没有对 C/C++ 编译器中未定义行为的更多了解,这是不可能的。



目录
相关文章
|
2天前
|
移动开发 监控 数据可视化
通过C++实现对管理员工上网行为的数据挖掘与可视化
这篇文章介绍了如何使用C++进行员工上网行为的监控数据挖掘与可视化。首先,通过读取系统日志收集上网数据,然后进行数据分析,包括统计访问频率和识别异常行为。接着,利用数据可视化工具展示结果。最后,讨论了如何将监控数据自动提交到网站,以实现实时监控和问题响应。示例代码展示了使用Boost.Asio库创建HTTP客户端上传数据的基本过程。
99 2
|
2天前
|
安全 编译器 程序员
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
【C++ 修饰符关键字 explicit 】掌握C++中的explicit :构造函数行为和初始化综合指南
118 3
|
2天前
|
存储 缓存 算法
高效编程:我们应该了解哪些编译器优化技术?如何做出成熟的优化行为,掌握C++编程中的编译器优化艺术。
高效编程:我们应该了解哪些编译器优化技术?如何做出成熟的优化行为,掌握C++编程中的编译器优化艺术。
102 4
|
2天前
|
算法 安全 大数据
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析(二)
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析
58 0
|
2天前
|
编译器 C++
C++:编译器对被const修饰变量的处理行为(替换)
C++:编译器对被const修饰变量的处理行为(替换)
14 0
|
2天前
|
算法 安全 数据安全/隐私保护
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析(一)
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析
61 0
|
2天前
|
存储 算法 编译器
【C++ 模板应用】模板哪些行为属于多态哪些行为属于泛型编程?
【C++ 模板应用】模板哪些行为属于多态哪些行为属于泛型编程?
26 0
|
2天前
|
C++
c++ - 警告 : treating ‘c-header‘ input as ‘c++-header‘ when in C++ mode, 此行为已弃用
c++ - 警告 : treating ‘c-header‘ input as ‘c++-header‘ when in C++ mode, 此行为已弃用
|
2天前
|
编译器 C语言 C++
C/C++未定义行为的例子汇总
C/C++未定义行为的例子汇总
|
11月前
|
C语言 C++
C++ 链接库顺序导致的符号未定义问题
C++ 链接库顺序导致的符号未定义问题
85 0