C ++最早的未定义行为可以表现出来的是什么?

问题描述 投票:10回答:5

我知道未定义的行为可能会导致任何事情,这使得任何包含UB的程序都可能毫无意义。我想知道是否有任何方法可以确定程序中最早的一点,即未定义的行为可能会导致问题。这是一个例子来说明我的问题。

void causeUndefinedBehavior()
{
   //any code that causes undefined behavior
   //every time it is run
   char* a = nullptr;
   *a;
}


int main()
{
 //code before call
 //...
 causeUndefinedBehavior();
 //code after call
 //...
}

根据我的理解,可能引发未定义行为的可能时间(不一定表现出来)是:

  1. 当编译causeUndefinedBehavior()时。
  2. 当编译main()时。
  3. 在程序运行时。
  4. 当时causeUndefinedBehavior()被执行。

或者,对于每个案例和每个实现,未定义的行为都会被完全不同?

另外,如果我注释掉调用causeUndefinedBehavior()的行,是否会消除UB,或者它是否仍然在程序中,因为包含UB的代码被编译了?

c++ undefined-behavior
5个回答
4
投票

正如您的代码在某种程度上所展示的那样,未定义的行为几乎总是在尝试行为时的运行时状态。稍微修改一下你的代码会让这很痛苦:

void causeUndefinedBehavior()
{
   //any code that causes undefined behavior
   //every time it is run
   char* a = nullptr;
   *a;
}


int main()
{
 srand(time(NULL));
 //code before call
 //...
 if (rand() % 973 == 0)
    causeUndefinedBehavior();
 //code after call
 //...
}

您可以执行此操作一千次或更多次,并且永远不会跳过UB执行条件。这并没有改变函数本身显然是UB的事实,但是在编译时在调用者的上下文中检测它并不是微不足道的。


2
投票

我认为这取决于未定义行为的类型。会影响结构偏移的事情可能会导致未定义的行为,这会显示触及该结构的任何时间代码。

但是,一般情况下,大多数未定义的行为都是在运行时发生的,这意味着只有执行该代码才会发生未定义的行为。

For example,修改字符串文字的尝试有未定义的行为:

char* str = "StackOverflow";
memcpy(str+5, "Exchange", 8);    // undefined behavior

memcpy执行之前,这种“未定义的行为”不会发生。它仍然可以编译成完美的代码。

另一个例子是省略具有非void返回类型的函数的返回:

int foo() {
    // no return statement -> undefined behavior.
}

在这里,正是在foo返回时发生了未定义的行为。 (在这种情况下,在x86上,无论发生在eax寄存器中的是函数的结果返回值。)

通过启用更高级别的编译器错误报告(例如,-Wall on GCC),可以识别其中许多场景。


2
投票

“未定义的行为”意味着语言定义不会告诉您程序将执行的操作。这是一个非常简单的陈述:没有信息。您可以推测您喜欢的实施可能会做什么或不做什么,但除非您的实施记录它的作用,否则您只是在猜测。编程不是猜测;这是关于知道的。如果程序的行为未定义,请修复它。


1
投票

虽然它是“未定义的行为”,但在给定特定编译器的情况下,它将具有某种可预测的行为。但是因为它是未定义的,在不同的编译器上,它可能导致在complilation / runtime的任何点发生该行为


0
投票

这使得任何包含UB的程序都可能毫无意义

不太对劲。程序不能“包含”UB;当我们说“UB”这个简称:程序的行为是不确定的。所有的!

因此,该计划从一开始就不仅仅是潜在的,而且实际上是毫无意义的。

[intro.execution]/5:执行格式良好的程序的符合实现应该产生与具有相同程序和相同输入的抽象机的相应实例的可能执行之一相同的可观察行为。但是,如果任何此类执行包含未定义的操作,则此国际标准不要求使用该输入执行该程序的实现(甚至不考虑第一个未定义操作之前的操作)。

© www.soinside.com 2019 - 2024. All rights reserved.