getc是宏还是函数? [英] Is getc a macro or a function?

查看:210
本文介绍了getc是宏还是函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到getcfgetc之间的区别.当时我看到这样的声明:

I tried to find the difference between getc and fgetc. At that time I saw a statement like:

getc和fgetc之间的区别在于,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实现?

So, is getc really a function or it is a macro? If it is macro, it calls some other function. So, is getc implemented in C or not?

推荐答案

getc和fgetc之间的区别在于,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.

那是不正确的.

除少数例外, any C标准库函数可以另外实现为宏,但是对该宏的编写方式有一些限制(因此该宏仍可以用作如果它是一个函数).

With a few exceptions, any C standard library function may additionally be implemented as a macro, but there are some restrictions on how that macro can be written (so that the macro can still be used as if it were a function).

引用 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):

What's special about getc is that one of those restrictions may be relaxed (7.21.7.5):

getc 功能等效于 fgetc ,不同之处在于 作为宏实施,它可能对 stream 的评估超过 一次,因此该参数绝不能是带有副作用的表达式.

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.

fgetcgetc的声明是:

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

stream参数(例如,在诸如fgetc(stdin)getc(file)之类的调用中,几乎始终是没有副作用的表达式,但是规则仍然禁止将fgetc定义为对其参数进行更多计算的宏)一次,以防程序员编写fgetc(file_list[i++])之类的代码.getc的规则被放宽,因此可以将其定义为一个宏(在某些情况下效率可能更高),同时可能破坏诸如getc(file_list[i++])之类的内容. >.

The stream argument (for example, in a call like fgetc(stdin) or getc(file) is almost always an expression without side effects, but the rules still forbid defining fgetc as a macro that evaluates its argument more than once, just in case a programmer writes something like fgetc(file_list[i++]). The rule is relaxed for getc so that it can be defined as a macro (which can be significantly more efficient in some cases), while potentially breaking something like getc(file_list[i++]).

fgetc的情况下,将其实现为宏而不是仅将其实现为函数可能不会有太多优势.关键是该标准明确允许它.

In the case of fgetc, there probably wouldn't be much advantage in implementing it as a macro rather than just as a function. The point is that the standard explicitly permits it.

那么,getc是否用C实现?

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

Maybe. There's no requirement for any C library function to be implemented in C. Some functions might be implemented in assembler, or in any other language -- or they might be compiler intrinsics. Usually most or all C standard library functions are implemented in C, but the standard only specifies how they work, not how they're written.

这篇关于getc是宏还是函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆