gpt4 book ai didi

c - getc() 作为宏和 C 标准库函数定义,连贯吗?

转载 作者:太空狗 更新时间:2023-10-29 17:22:39 24 4
gpt4 key购买 nike

[7.1.4库函数的使用]中,我读到:

Any function declared in a header may be additionally implemented as a function-like macro defined in the header...

Any invocation of a library function that is implemented as a macro shall expand to code that evaluates each of its arguments exactly once...

然后对于getc[7.21.7.5的getc函数]:

The getc function is equivalent to fgetc, except that if it is implemented as a macro, it may evaluate stream more than once, so the argument should never be an expression with side effects.

是否定义了getc:

  • 与库函数定义相矛盾?
  • 反过来呢?
  • 这是否与标准不一致?
  • 或者这是否意味着如果 getc 被单独实现(似乎不合规但是?)作为一个宏它可能会对其参数求值两次?

最佳答案

标准中的定义是连贯的;您对它们的尝试解释并不完全连贯。

标准说......

ISO/IEC 9899:2011 (C11) 标准说(引用 §7.1.4 中的更多 Material ,并将一大段的部分内容分成几段):

Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: …

Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro.

Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro.185) The use of #undef to remove any macro definition will also ensure that an actual function is referred to.

Any invocation of a library function that is implemented as a macro shall expand to code that evaluates each of its arguments exactly once, fully protected by parentheses where necessary, so it is generally safe to use arbitrary expressions as arguments.186) Likewise, those function-like macros described in the following subclauses may be invoked in an expression anywhere a function with a compatible return type could be called.187)

185) This means that an implementation shall provide an actual function for each library function, even if it also provides a macro for that function.

186) Such macros might not contain the sequence points that the corresponding function calls do.

187) Because external identifiers and some macro names beginning with an underscore are reserved, implementations may provide special semantics for such names. For example, the identifier _BUILTIN_abs could be used to indicate generation of in-line code for the abs function. Thus, the appropriate header could specify

#define abs(x) _BUILTIN_abs(x)

for a compiler whose code generator will accept it. In this manner, a user desiring to guarantee that a given library function such as abs will be a genuine function may write

#undef abs

whether the implementation’s header provides a macro implementation of abs or a built-in implementation. The prototype for the function, which precedes and is hidden by any macro definition, is thereby revealed also.

请特别注意脚注 185 的内容。

您还引用了来自 §7.21.7.5 的 getc 定义中的 Material :

The getc function is equivalent to fgetc, except that if it is implemented as a macro, it may evaluate stream more than once, so the argument should never be an expression with side effects.

(其中 stream 是用于 getc 的参数的名称。)

解释标准

你问(稍微解释一下):

  • getc 的定义是否与库函数的定义相矛盾?

    没有。 §7.1.4 开头说'除非明确说明',然后给出一系列通用规则,然后getc 的规范明确说明否则。

  • 反之亦然吗?

    没有。 §7.1.4 的开头部分说任何特定函数的规范都可以覆盖 §7.1.4 中的一般性规定。

  • 这是否与标准不一致?

    我看不出这里有什么矛盾。

  • 或者这是否意味着如果 getc 仅作为宏实现(这似乎不符合要求但是……),宏可能会对其参数求值两次?

    1. getc 不能单独实现为宏(脚注 185)。还必须有一个实现相同功能的实际函数。实现可以很简单:

      int (getc)(FILE *fp) { return getc(fp); }
    2. 明确允许实现 getc 的宏对其参数求值多次(但不是必须这样做)。 §7.21.7.5 中的规范明确表示可以,而 §7.1.4 中的规范明确表示允许 §7.21.7.5 更改通常禁止此类行为的 §7.1.4 的一般规则。

关于c - getc() 作为宏和 C 标准库函数定义,连贯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39793885/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com