澄清C中实现定义的行为

时间:2012-12-04 07:02:02

标签: c types implementation

作为C中实现定义行为的示例.C标准表示数据类型的大小是实现定义的。所以,说sizeof(int)是实现定义的。

  1. 此实现定义的行为是否意味着size(int)是平台相关的还是由编译器供应商或两者定义的?

  2. 编译代码后,当我在不同版本的平台上运行时,实现依赖性仍然适用吗?在一个平台上编译实现定义代码并在其他平台上运行它会导致性能损失吗?

5 个答案:

答案 0 :(得分:3)

是的,实现定义意味着它取决于平台(Architecture + OS ABI +编译器)。

是的,实现定义的功能可能因平台的不同版本而异。

答案 1 :(得分:3)

  

此实现定义的行为是否意味着size(int)是平台相关的还是由编译器供应商或两者定义的?

原则上,编译器供应商可以做出决定。实际上,如果编译器想要发出直接调用系统库的代码,那么它必须遵循与系统相同的“ABI”(应用程序二进制接口),其中ABI将指定{{1的大小}}。因此,编译器供应商将“决定”使其达到ABI所说的大小。

针对多个平台和体系结构的编译器将作为每个平台配置的一部分单独做出决策。然后,每个目标代表一个不同的 C实现,即使您将其视为“相同的编译器”。

您可以编写符合要求的C实现,其中int与运行该程序的操作系统的大小不同。人们很少这样做,标准库在进行系统调用时必须跳过额外的箍。它可能是模拟器的一部分,但是你可能会合理地认为“平台”是模拟平台,而不是具有不同大小的int的主机平台。

  

编译代码后,当我在不同版本的平台上运行时,实现依赖性仍然适用吗?

int是一个编译时常量,这意味着编译器发出的代码可能会假定某个值。然后,该二进制代码无法在具有不同大小sizeof(int)的平台的不同版本上正确运行。

  

在一个平台上编译实现定义代码并在其他平台上运行它会导致性能损失吗?

如果它完全有效,那么就没有特别的理由认为会有性能损失。它通常根本不起作用(见上文),因为用于一个平台的二进制代码通常不适用于另一个平台。如果平台足够相似以至于它确实有效,那么编译器为一个实现的优化可能不是另一个优化的优化。在这种情况下,会出现性能损失,修复方法是重新编译针对正确(版本)平台的代码。

这种情况确实发生在ARM上,在较小程度上发生在x86上。过去不同的芯片提供了基本相同的指令集,但是某些芯片上的一些指令相对于其他指令具有显着不同的成本。假设指令X快速的优化可能是指令X缓慢的不同芯片上的错误优化。可以想象,这种差异并不会使芯片制造商在编译器供应商中非常受欢迎,对于汇编程序员来说更是如此。

答案 2 :(得分:2)

  

此实现定义的行为是否意味着size(int)是平台相关的还是由编译器供应商或两者定义的?

在C标准术语中,实现是编译器。

以下是术语实施的C标准中的实际定义:

  

(C99,3.12p1)实施:在特定控制选项下的特定翻译环境中运行的特定软件集,用于执行特定程序的转换,并支持特定功能的执行。执行环境

答案 3 :(得分:0)

size(int)确实依赖于实现。它与性能无关,而是与您正在使用的平台的架构有关。 32位宽的CPU的行为与64位宽的CPU或者16位宽的CPU不同。

这是他们主要依赖于平台所指的内容,但也存在交叉编译的问题,这会带来更多问题。您可以使用-m之类的标志来指定架构和宽度,这会导致代码在不同平台下运行,而不是最初编译时。

答案 4 :(得分:0)

根据C-标准

  

ISO / IEC 9899:1999§3.4.1

     

1 实施定义的行为
  未指明的行为,其中每个实现记录了如何做出选择

这意味着编译器中记录的行为是implementation defined

记录了

sizeof()

  

2示例:实现定义行为的一个示例是高阶位的传播   当有符号整数向右移位时。

附件J'可移植性问题'包括未指定行为(J.1),未定义行为(J.2),实现定义行为(J.3)和区域特定行为(J.4)的列表。 / p>