C ++未定义的行为与否? (再次)

时间:2012-02-28 17:17:41

标签: c++ undefined-behavior

我查看了一堆问题并且看不到这个,虽然我已经确定它已经在某个地方了。所以我道歉并认为这将被关闭,但希望有人会先确认我的答案!

我认为这是正确的:

while (--len > -1 && ptr = str[len])

定义良好(未定义!)行为?我理解这一点的方式是&&是一个序列点,短路的工作方式意味着应该首先评估--len > -1,如果它不安全则不会发生第二部分。

我不确定我在这个思考过程中是否正确。

5 个答案:

答案 0 :(得分:5)

这是定义的行为,因为&&sequence point,您理解它的方式是正确的。从链接的维基百科页面:

  

在C [2]和C ++中,[3]序列点出现在以下地方:

     

在评估&&和/或(逻辑AND),|| (逻辑OR)和逗号运算符。例如,在表达式* p ++!= 0&& * q ++!= 0,在尝试访问q之前,子表达式* p ++!= 0的所有副作用都已完成。

但是,这并不能确保--len不会导致索引超出str的范围。如果str是以空值终止的str,您可以更改为:

while (--len > -1 && len < strlen(str) && ptr = str[len])

答案 1 :(得分:1)

是的,这是正确的。订单是:

  1. len递减
  2. (新值)len-1
  3. 进行比较
  4. 如果(2)评估为真,ptr = str[len]

答案 2 :(得分:0)

如果ptr = str[len]为false,则认为--len > -1未执行是正确的(可能是未定义的行为,对于索引数组,len太大了,我认为它不是你的恐惧)。如果len事先是INT_MIN,那么--len可能是一个未定义的行为(如果len是一个sanely,则再次不可能)因为带符号算术的溢出是一个未定义的行为。

答案 3 :(得分:0)

while (--len > -1 && ptr = str[len])

在len = 1的例子中(如果len是int),事情是这样的:

1) len = len-1=0
2) ptr = str[0] 

2)是因为if if语句的第一部分减少了len。 那是你想要的吗?

但行为被定义,首先检查第一部分。

答案 4 :(得分:0)

这实际上没问题。这里的关键是你不是不止一次写len

首先你预先递减len。然后检查len的递减值是否至少为0.接下来,将str[len](使用递减的len)分配到ptr。最后检查ptr是否为非null,如果是,则执行while循环语句。

请注意,如果len是无符号的-1将被提升为无符号,并且循环肯定会在第一次迭代时失败。此外,即使len已签名,如果它具有未指定的最小int值(std::numeric_limits<int>::min())递减。