C关于不可移植项目的标准未定义行为



C99标准对未定义的行为给出了以下定义:

使用不可移植或错误的程序结构或错误数据时的行为,而本国际标准对此没有任何要求。

如果你正在进行一个永远不需要可移植的项目,也就是说,编译器和微控制器不会改变,你能安全地使用不可移植的结构吗?国际标准称,如果这些结构是由你使用的编译器或微控制器定义的,它们会导致未定义的行为?

您可以随时从硬件、操作系统和编译器供应商那里寻找额外的保证。"未定义的行为"为符合添加保证和规则的实现留出了空间。

实现可以自由定义和记录一些C未定义的行为。

例如,C99的基本原理文件说:

未定义的行为允许实现者不捕捉某些难以诊断的程序错误。它还确定了可能的一致语言扩展领域:实现者可以通过提供官方未定义行为的定义来增强语言。

例如,gcc定义了一些关于按位移位运算符的未定义行为:

GCC不使用C99中给出的自由度,仅用于处理签名的"<lt;'未定义[…]

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

Code在MAX_INT中添加了1,在一个无法保证会发生什么的平台上,也无法保证会出现什么。如果代码在保证结果为MIN_INT的平台上执行这样的操作,则保证结果为MIN_INT。

请注意,在许多情况下(包括整数溢出),平台不做任何保证,但会经常以某种方式运行。未定义行为在此类平台上仍然是未定义行为,因为无法保证任何特定操作都会按预期进行。例如,如果SHORT_MAX是32767,则序列short foo=32767; foo++; int bar=foo;很可能导致bar等于32768而不是-32768,即使保证二进制补码翻转的编译器必须返回后一个结果。

即使您在同一平台上使用相同的IDE,未定义的行为仍然是不安全的!

例如,此代码:

char *p = (char*)0x12345678;
char ch = *p;

这是一种未定义的行为,它取决于内存分配。有时,它会出现分段错误,有时,它不会。

最新更新