ANSI C定义的一些关于可移植性的术语说明

ANSI C标准定义了一些术语,用于描述某种编译器的特点。对这些术语有一个比较好的了解,对于提供代码的可移植性和错误的排查都有帮助的。

  1. 不可移植的代码(unportable code)

    由编译器定义的(implementation-defined): 由编译器设计者决定采取何种行动,也就是说在不同的编译器中所采取的行为可能并不相同,但是它们都是正确的。每个编译器的文档会给出具体的行为方式。

    例如: 当整数向右移位时,要不要扩展符号位。

    未指定的(unspecified): 在某些正确情况下的做法,标准并未规定应该怎样做。

    例如:参数求值的顺序。

  2. 坏代码(bad code)

    未定义的(undefined): 在某些不正确情况下的做法,标准并未规定应该怎样做。编译器可以什么也不做,也可以发出一条警告信息,或者中止程序。

    例如:当一个有符号整数溢出时该采取什么行动。

    约束条件(a constraint): 这是一个必须遵守的限制或要求。如果你不遵守,那么你的程序的行为就会变成像上面所说的属于未定义的。分辨某种东西是否是一个约束条件是容易的,因为标准的每个主题都附有一个“约束(constraint)“小节,列出了所有的约束条件。

    例如:%操作符的操作数必须属于整形。所以在非整形数上使用%操作符肯定会引发一条错误信息。

    标准规定编译器只有在违反语法规则和约束条件的情况下,才能产生错误信息!这意味着所有不属于约束条件的语义规则你都可以不遵循,而且由于这种行为属于未定义的行为,编译器可以采取任何行动,甚至不必通知你。

    不属于约束条件的例子:所有在C语言标准头文件中声明的标识符均保留,所以不能声明一个叫malloc()的函数,因为在标准头文件中已经有一个这样的函数。但是由于这个规定不是约束条件,因此可以违反它,而且编译器甚至可以不警告你。

  3. 可移植的代码

    严格遵循标准的(strictly-conforming): 一个严格遵循标准的程序应该是:

    • 只使用已确定的特性

    • 不突破任何由编译器实现的限制

    • 不产生任何依赖由编译器定义的或未指定的或未定义的特性的输出

    这样规定的主要目的就是最大限度地保证可移植性。这样,不论你在什么平台上运行严格遵循标准的程序都会产生相同的输出。

    遵循标准的(strictly-conforming): 一个遵循标准的程序可以依赖一些某种编译器特有的不可移植的特性。所以,一个程序有可能在一个特定的编译器里是遵循标准的,但在另一个编译器里却是不遵循标准的。

C语言标准规范中的Annex J (informative) Portability issues章节对哪里行为属于未指定的,哪里行为属于未定义的等有详细的总结,可以参考。


参考文献
1. ISOIEC 9899-201x-C语言标准规范
2. 《c专家编程》

猜你喜欢

转载自blog.csdn.net/rex_nie/article/details/80204667
今日推荐