getc 是宏还是函数?
Is getc a macro or a function?
我试图找到 getc
和 fgetc
之间的区别。当时看到这样的说法:
The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro.
那么,getc
到底是一个函数还是一个宏?如果它是宏,它会调用其他一些函数。那么,getc
是否用 C 实现?
getc
是 C99 标准第 7.21.7.5 节中规定的函数,可能会也可能不会作为宏实现:
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.
它不能正确处理有副作用的参数。例如--
int c = getc(*fpp++);
The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro.
这是不正确的。
除少数例外,any C 标准库函数可以另外实现为宏,但是对于如何编写该宏有一些限制(以便宏仍然可以像函数一样使用。
引用 N1570 第 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, fully protected by
parentheses where necessary, so it is generally safe to use arbitrary
expressions as arguments.
getc
的特别之处在于其中一项限制可能会放宽 (7.21.7.5):
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.
fgetc
和getc
的声明是:
int fgetc(FILE *stream);
int getc(FILE *stream);
stream
参数(例如,在像 fgetc(stdin)
或 getc(file)
这样的调用中几乎总是一个没有副作用的表达式,但规则仍然禁止定义 fgetc
作为一个对其参数求值不止一次的宏,以防程序员编写类似 fgetc(file_list[i++])
的代码。对于 getc
的规则放宽了,因此它可以被定义为一个宏(这可以显着在某些情况下效率更高),同时可能会破坏 getc(file_list[i++])
.
在 fgetc
的情况下,将其实现为宏而不是函数可能不会有太大优势。关键是标准明确允许它。
So, is getc
implemented in C or not?
也许吧。 any C 库函数不需要在 C 中实现。某些函数可能在汇编程序或任何其他语言中实现——或者它们可能是编译器内部函数。通常大多数或所有 C 标准库函数 都是 在 C 中实现的,但标准只规定了它们的工作方式,而不是它们的编写方式。
我试图找到 getc
和 fgetc
之间的区别。当时看到这样的说法:
The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro.
那么,getc
到底是一个函数还是一个宏?如果它是宏,它会调用其他一些函数。那么,getc
是否用 C 实现?
getc
是 C99 标准第 7.21.7.5 节中规定的函数,可能会也可能不会作为宏实现:
The
getc
function is equivalent tofgetc
, except that if it is implemented as a macro, it may evaluatestream
more than once, so the argument should never be an expression with side effects.
它不能正确处理有副作用的参数。例如--
int c = getc(*fpp++);
The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro.
这是不正确的。
除少数例外,any C 标准库函数可以另外实现为宏,但是对于如何编写该宏有一些限制(以便宏仍然可以像函数一样使用。
引用 N1570 第 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, fully protected by parentheses where necessary, so it is generally safe to use arbitrary expressions as arguments.
getc
的特别之处在于其中一项限制可能会放宽 (7.21.7.5):
The
getc
function is equivalent tofgetc
, except that if it is implemented as a macro, it may evaluatestream
more than once, so the argument should never be an expression with side effects.
fgetc
和getc
的声明是:
int fgetc(FILE *stream);
int getc(FILE *stream);
stream
参数(例如,在像 fgetc(stdin)
或 getc(file)
这样的调用中几乎总是一个没有副作用的表达式,但规则仍然禁止定义 fgetc
作为一个对其参数求值不止一次的宏,以防程序员编写类似 fgetc(file_list[i++])
的代码。对于 getc
的规则放宽了,因此它可以被定义为一个宏(这可以显着在某些情况下效率更高),同时可能会破坏 getc(file_list[i++])
.
在 fgetc
的情况下,将其实现为宏而不是函数可能不会有太大优势。关键是标准明确允许它。
So, is
getc
implemented in C or not?
也许吧。 any C 库函数不需要在 C 中实现。某些函数可能在汇编程序或任何其他语言中实现——或者它们可能是编译器内部函数。通常大多数或所有 C 标准库函数 都是 在 C 中实现的,但标准只规定了它们的工作方式,而不是它们的编写方式。