getc是宏还是函数?

时间:2015-09-23 14:32:13

标签: c linux unix macros

我试图找出getcfgetc之间的区别。那时我看到了一个声明:

  

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

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

2 个答案:

答案 0 :(得分:6)

  

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

这是不正确的。

除了少数例外,任何 C标准库函数可能还可以作为宏实现,但是对于如何编写宏有一些限制(这样宏仍然可以用作如果它是一个功能)。

引用N1570第7.1.4节:

  

标头中声明的任何函数都可以另外实现为a   标题中定义的类似函数的宏,[...]任何a的调用   作为宏实现的库函数应扩展为代码   它只准确地评估它的每个参数一次,完全受到   必要时用括号括起来,所以通常可以安全使用   表达式作为参数。

getc的特殊之处在于可以放宽其中一项限制(7.21.7.5):

  

getc 功能相当于 fgetc ,除非是   它是作为宏实现的,它可以评估 stream   曾经,所以论证永远不应该是一个有副作用的表达。

fgetcgetc的声明是:

int fgetc(FILE *stream);
int getc(FILE *stream);

stream参数(例如,在fgetc(stdin)getc(file)之类的调用中几乎总是一个没有副作用的表达式,但规则仍然禁止将fgetc定义为一个宏,它不止一次地评估它的参数,以防程序员写出像fgetc(file_list[i++])这样的东西。getc放宽了规则,这样就可以将它定义为一个宏(可以显着提高效率)在某些情况下),虽然可能会破坏像getc(file_list[i++])这样的东西。

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

  

那么,是否在C中实现getc

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

答案 1 :(得分:1)

getcC99 standard section 7.21.7.5中所述的功能,可能会也可能不会被macro实施。

  

7.21.7.5 -

     

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

对于具有副作用的参数(流参数)值,它无法正常工作。例如 -

int c=getc(*f++);