C99:嵌入式函数是否仍然是序列点?

问题描述 投票:0回答:2

adding

inline
函数表明,调用该函数的编译器尽可能快。 (ISO/IEC 9899:1999§6.7.4.5)

依赖于优化级别,编译器还可能决定“内联”函数(用指令代替呼叫)。

ISO / IEC 9899:1999在附件C“序列点” /第5.1.2.3节中定义

在评估了参数之后(6.5.2.2)。

(和其他)作为序列点。 我的问题:

是什么从通过内在的函数调用来定义了C99抽象机器?即使优化删除了调用,这些序列点是否也需要保留?

当使用积极优化时,典型的嵌入式C编译器在C99模式下的行为是什么?

  1. 5.1.2.3程序执行
c c99
2个回答
2
投票

  1. ...(和其他)作为序列。
没有其他保证的序列点,除了参数评估之后,但在调用函数之前。嵌入函数也是如此。除了内在的情况外,参数评估可能会或可能不会取决于该评估是否包含所需的副作用(在下面进一步说明)。
功能可能具有或可能没有附件C中定义的完整表达式,在这种情况下,功能主体内部有序列点。

2
投票

是什么从通过内在的函数调用来定义了C99抽象机器?即使优化删除了调用,这些序列点是否也需要保留?

一般 - 不是C99或封闭函数的特定 - C标准称

需要副作用,例如C99 5.1.2.3(强调矿山):


在抽象的机器中,所有表达式均按语义规定评估。一个 实际实施不必评估表达式的一部分,如果它可以推断出它的一部分 值不使用
    没有产生所需的副作用
  1. (包括由 调用功能或访问挥发性对象)。
序列不是“圣洁”,只需要副作用。所需的副作用无法优化,但是可以优化运行速度,可以在序列点等上重新排序等。
唯一既无法优化也无法重新排序的副作用就是访问。如果发生对对象的访问发生,则编译器必须在下一个序列点之前进行评估并进行此操作,这意味着在该特定情况下,序列点得到尊重。在C23中,这是“根据抽象机器的规则严格评估对象的挥发性访问”。

对于所有其他情况,编译器都可以自由执行上述优化。只要不影响程序行为,也可以免费进行指令重新排序。 例如,示例省略了整个功能调用,Skip写入呼叫者未使用(“需要”)的本地变量,重新订购函数调用等。这些优化是可能的。 内部界限唯一不同的是,在其他地方定义的具有外部链接的正常函数无法对呼叫者侧的参数状态进行假设。因此,通常需要在调用函数之前对函数调用参数进行评估和复制到临时位置。但是,当函数被内衬时,编译器可能会得出有关用作参数的变量并相应优化的进一步结论。

当使用积极优化时,典型的嵌入式C编译器在C99模式下的行为是什么。

toshosing to to to to to to to to to to to to to to to to to to sim。当函数内衬时,将跳过函数调用,参数通过ABI传递部分也是如此。本来可以通过的变量仍然可以存储在编译器已经存储的任何地方,例如在快速寄存器中而不是在堆栈中存储,如果函数调用ABI需要该功能。这意味着性能可能还会有额外的好处
尽管如此,历史上,各种或多或少的异国情调的嵌入式系统编译器通常在优化代码方面做得很糟糕。许多人也遭受C符合不佳的困扰。这些编译器中有许多仍在市场上。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.