“未定义的行为”总是未定义?

时间:2014-06-12 07:43:04

标签: c undefined-behavior

C中可能存在导致UB的事情。

他们中的大多数都可以这样做,但有几个实现定义的行为更合乎逻辑。让我举个例子:

关于<<运营商,

  

如果E1具有带符号类型和非负值,并且E1×2 E2可在结果类型中表示,那么这就是结果值;否则,行为是未定的。

这意味着

signed char r = 0x40;
r <<= 2;

是UB,其中IB将IMO更合乎逻辑。

是否允许实现定义此处发生的事情?

3 个答案:

答案 0 :(得分:2)

来自C标准:

  

符合标准的托管实现应接受任何严格符合的程序......符合要求的实现可能具有扩展(包括附加的   库函数),只要它们不改变任何严格符合的行为   程序

换句话说,实现可以自由地保证特定行为,否则将是未定义的行为。它不能以改变定义的行为的方式来实现。

答案 1 :(得分:2)

问题是:

signed char r = 0x40;
r <<= 2;

不是未定义的行为。

C说:

r <<= 2;

相当于

r = r << 2;

唯一差异r仅评估一次。

r << 2等同于(int) r << 2,与<<相同,整数促销适用于每个操作数。

所以我们实际上有:

r <<= 2;

相当于

r = 0x100;

此赋值也不是未定义的行为。 0x100在分配之前转换为signed char,此转换由c99,6.3.1.3p3规定,其中此处的转换是实现定义的。

现在,如果它是未定义的行为,“实现者可以通过提供官方未定义行为的定义来扩充语言”(来自c99 Rationale文档)(这在c99,4.p6中说明)

答案 2 :(得分:1)

ISO C所说的意义上的未定义行为。如果某个实现定义某个特定的行为(在ISO C中未定义),那么这样做是完全有效的。它不符合ISO C标准。

GCC有一些在ISO C中未定义但在GNU C中有效的扩展。取一个函数/ void的大小(sizoof (a_function)sizeof(void))。

遵循ISO C的主要原因是使代码更具可移植性。因此,如果X的行为未定义(在ISO C中),并且您的实现定义了X的有效行为,则您的代码不可移植其他实现可能没有为X定义任何内容。