我翻遍了一堆问题,看不到这个,尽管我确定它已经在某个地方了。所以我很抱歉,并认为这将会结束,但希望有人会首先确认我的答案!C++未定义行为还是不行? (再次)
我是在想,纠正:
while (--len > -1 && ptr = str[len])
被很好地定义(没有未定义!)的行为吗?我理解的方式是,& &是一个序列点,短路的方式将起作用,这意味着--len > -1
应该首先评估,如果它不安全,则不会发生第二部分。
虽然我不确定自己在这个思维过程中是否正确。
我翻遍了一堆问题,看不到这个,尽管我确定它已经在某个地方了。所以我很抱歉,并认为这将会结束,但希望有人会首先确认我的答案!C++未定义行为还是不行? (再次)
我是在想,纠正:
while (--len > -1 && ptr = str[len])
被很好地定义(没有未定义!)的行为吗?我理解的方式是,& &是一个序列点,短路的方式将起作用,这意味着--len > -1
应该首先评估,如果它不安全,则不会发生第二部分。
虽然我不确定自己在这个思维过程中是否正确。
这被定义行为&&
是一个sequence point和你理解它的方式是正确的。从链接的维基百科页面:
在C [2]和C++,[3]顺序点发生在以下位置:
的& &的左边和右边的操作数的评价(逻辑之间),|| (逻辑OR)和逗号运算符。例如,在表达式* p ++!= 0 & & * q ++!= 0中,子表达式* p ++!= 0的所有副作用在任何尝试访问q之前完成。
但是,这并不确保--len
不会导致索引超出str
的范围。如果str
是一个空结束的str
你可以改变:
while (--len > -1 && len < strlen(str) && ptr = str[len])
非常感谢:) – 2012-02-28 18:16:23
@hmjd:我会避免在循环的每次运行时重新计算'strlen',它肯定是浪费。如果'len'不如'strlen(str)'开头,那么递减它不应该改变这个事实。当然,这个假设'str'本身不移动,在这里看起来就是这种情况。 – 2012-02-28 18:16:50
是的,这是正确的。顺序为:
len
递减len
如果(2)评估以真相比-1
ptr = str[len]
感谢您的快速回答;) – 2012-02-28 19:35:50
您是认为ptr = str[len]
不执行,如果--len > -1
是假的权利(这可能是一个未定义的行为是len为过大的索引数组,我认为这不是你所害怕的)。如果len事先是INT_MIN,则--len
可能是一个未定义的行为(如果len被初始化,则不会很有可能),因为有符号算术的溢出是未定义的行为。
while (--len > -1 && ptr = str[len])
例如用于LEN = 1
(如果len为INT)的东西是这样认为:
1) len = len-1=0
2) ptr = str[0]
2)是因为,如果LEN的递减的if语句的第一部分。 是你想要的吗?
但是行为是被定义的,第一部分将被首先检查。
这实际上是确定的。这里的关键是你不会多次写入len
。
首先你先递减len
。然后检查减量值len
是否至少为0.接下来,将str[len]
(使用递减的len
)分配到ptr
。最后检查ptr
是否为非空,如果是,则执行while
循环语句。
请注意,如果len
未签名,则-1
将被提升为无符号,并且该循环几乎肯定会使第一次迭代失败。此外,即使len
如果具有未指定的最小int值(std::numeric_limits<int>::min()
)递减,也会被签名。
*这里的关键是你不会多次写入len。*这不一定是问题。 'map [++ i] = i'只写入'i'一次,但尚未定义。 – 2012-02-28 18:18:03
取决于此语句之前len的值是多少。如果它是0或更大,该怎么办?那么将评估ptr = str [len]。 – Sid 2012-02-28 17:20:23
是的,好点。这在我的情况下并不危险,但我并没有首先考虑它是不好的。 :) – 2012-02-28 17:24:06