问题描述
大家好,
K& R(第7-5节)的讨论中有一句话说......
(第2段末尾,关于页面的中间)...在连接中
与getc和putc的描述...
"喜欢getchar和putchar, getc和putc可能是宏而不是
函数"
现在,最近,我问为什么va_list,va_arg,va_start等是宏,
和答案包括来自KT的这两个见解;
Hi All,
There is a line in the discussion of K&R (section 7-5) that says ...
(end of 2nd paragraph, about the middle of the page)...in connection
with the description of getc and putc...that
"Like getchar and putchar, getc and putc may be macros instead of
functions"
Now, recently, I asked why va_list, va_arg, va_start etc were macros,
and the answers included these two insights from KT;
a函数无法修改参数。
?* AC函数不能取一个类型名称作为参数
<<<<<<<
此声明的重要性(即与putchar /
getchar有关)与va_list中的宏有关。如果没有,那么
意义/洞察力应该归结为这个陈述吗?
像往常一样感谢。
a function can''t modify an argument.
?*A C function cannot take a?¨a type name as an argument
<<<<<<<
Is the significance of this statement ( ie relating to putchar/
getchar) related to macros in va_list at all. And if not, what
significance/insight should I attribute to this statement?
Thanks as usual.
推荐答案
如果它们是宏,通常是出于效率原因。
你需要知道getc()和putc()可能是
的原因,例如:
FILE * f =& array_of_open_files [0];
c = getc(f ++);
可能无法按预期执行,因为第一个参数
的getc()可能会被多次评估,从而导致意外
结果。如果getc()*必须*是一个函数,这不是问题。
If they are macros, it''s usually for efficiency reasons.
You need to KNOW if getc() and putc() might be macros for
reasons such as:
FILE *f = &array_of_open_files[0];
c = getc(f++);
might not do what you expect it to do because the first argument
of getc() might be evaluated more than once, causing unexpected
results. This is not an issue if getc() *MUST* be a function.
a函数无法修改参数。
?* AC函数不能取一个?类型名称为一个论点
<<<<<<<<
a function can''t modify an argument.
?*A C function cannot take a?¨a type name as an argument
<<<<<<<
你有没有想过getc(unsigned long *)能正常工作?
No.有很多不同的原因为什么某些东西可能是一个宏,
并且这些原因无需相关。
Have you ever expected getc(unsigned long *) to work correctly?
No. There are lots of different reasons why something might be a macro,
and those reasons need not be related.
哪个陈述?
代码可能被视为死,因为它永远无法到达。
猫可能被认为是''死',因为他们已经用.45击中了
头。
你觉得吗?这两个陈述是相关的吗?
Which statement?
Code may be considered ''dead'' because it can never be reached.
Cats may be considered ''dead'' because they have been shot through the
head with a .45 .
Do you think these two statements are related?
如果它们是宏,通常是出于效率原因。
你需要知道getc()和putc()可能是
的原因,例如:
FILE * f =& array_of_open_files [0];
c = getc(f ++);
可能无法按预期执行,因为第一个参数
的getc()可能会被多次评估,从而导致意外
结果。如果getc()*必须*是一个函数,这不是问题。
If they are macros, it''s usually for efficiency reasons.
You need to KNOW if getc() and putc() might be macros for
reasons such as:
FILE *f = &array_of_open_files[0];
c = getc(f++);
might not do what you expect it to do because the first argument
of getc() might be evaluated more than once, causing unexpected
results. This is not an issue if getc() *MUST* be a function.
如果库函数是作为宏实现的,则不允许
多次评估其参数。
摘录自7.1.4 p1:
任何以宏实现的库函数调用都将
扩展为完全评估每个参数一次的代码,完全在必要时用括号保护
,所以使用
任意表达式作为参数通常是安全的.162)
脚注162说:这些宏可能不包含
对应函数调用的序列点
(这是从WG14 / N1256复制.C99标准本身有相同的
措辞,但脚注编号为156)
换句话说,上面的代码是保证表现相同是否
getc()是一个宏还是一个函数。
Martien
-
|
Martien Verbruggen |我认为有一个世界市场可能是
|五台电脑。 - Thomas Watson,董事长
| IBM,1943
If a library function is implemented as a macro, it is not allowed to
evaluate its arguments more than once.
Excerpt from 7.1.4 p1:
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.162)
Footnote 162 says: Such macros might not contain the sequence points that the
corresponding function calls do
(This is copied from WG14/N1256. The C99 standard itself has identical
wording, except that the footnote number is 156)
In other words, the code above is guaranteed to behave identical whether
getc() is a macro or a function.
Martien
--
|
Martien Verbruggen | I think there is a world market for maybe
| five computers. -- Thomas Watson, chairman
| of IBM, 1943
[...]
[...]
令人惊讶的是,你没有引用所有
的麻烦而没有真正看到getc的描述
功能:
7.19.7.5 getc功能
[...]
2 getc功能相当于fgetc,除非如果它实现为一个宏,它可以评估一次超过
的流,所以参数永远不应该是一个带有
副作用。
-
我在我的DeathStation 9000上运行它,恶魔飞出了我的鼻子。 --Kaz
It is amazing that you went to all the trouble of quoting all
that without actually looking at the description of the getc
function:
7.19.7.5 The getc function
[...]
2 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.
--
"I ran it on my DeathStation 9000 and demons flew out of my nose." --Kaz
这篇关于第161页...文件访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!