getc是宏还是函数?

mrg*_*mrg 1 c unix linux macros

我试图找到之间的差异getcfgetc.那时我看到一个声明如下:

getc和fgetc之间的区别在于getc可以实现为宏,而fgetc不能实现为宏.

那么,getc真的是一个函数还是一个宏?如果它是宏,它会调用其他一些功能.那么,是否getc用C实现?

Kei*_*son 7

getc和fgetc之间的区别在于getc可以实现为宏,而fgetc不能实现为宏.

那是不对的.

除了少数例外,任何 C标准库函数都可以另外实现为宏,但是对于如何编写宏有一些限制(因此宏仍然可以像使用它一样使用).

引用N1570第7.1.4节:

在头中声明的任何函数可以另外实现为在头中定义的类函数宏,[...]作为宏实现的库函数的任何调用都应扩展为仅对其每个参数进行一次计算的代码,必要时用括号完全保护,因此使用任意表达式作为参数通常是安全的.

特别之处getc在于可以放宽其中一个限制(7.21.7.5):

getc函数等效于fgetc,除非它实现为宏,它可能会stream多次计算,因此参数永远不应该是带有副作用的表达式.

声明fgetcgetc是:

int fgetc(FILE *stream);
int getc(FILE *stream);
Run Code Online (Sandbox Code Playgroud)

stream参数(例如,像一个电话fgetc(stdin)getc(file)几乎总是无副作用的表达,但规则还是禁止定义fgetc为评估其参数不止一次,以防万一程序员喜欢写东西的宏fgetc(file_list[i++]),规则是放松因为getc它可以被定义为一个宏(在某些情况下可以显着提高效率),同时可能会破坏类似的东西getc(file_list[i++]).

在这种情况下fgetc,将它实现为宏而不仅仅是作为一个函数可能没有多大优势.重点是标准明确允许它.

那么,是否getc用C实现?

也许.不需要在C中实现任何 C库函数.某些函数可能以汇编程序或任何其他语言实现 - 或者它们可能是编译器内在函数.通常,大多数或所有C标准库函数都是用C实现的,但标准只规定了它们的工作方式,而不是它们的编写方式.