- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在[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...
然后对于getc
,[7.21.7.5的getc函数]:
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.
是否定义了getc
:
getc
被单独实现(似乎不合规但是?)作为一个宏它可能会对其参数求值两次?最佳答案
标准中的定义是连贯的;您对它们的尝试解释并不完全连贯。
ISO/IEC 9899:2011 (C11) 标准说(引用 §7.1.4 中的更多 Material ,并将一大段的部分内容分成几段):
Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: …
Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro.
Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro.185) The use of
#undef
to remove any macro definition will also ensure that an actual function is referred to.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.186) Likewise, those function-like macros described in the following subclauses may be invoked in an expression anywhere a function with a compatible return type could be called.187)
185) This means that an implementation shall provide an actual function for each library function, even if it also provides a macro for that function.
186) Such macros might not contain the sequence points that the corresponding function calls do.
187) Because external identifiers and some macro names beginning with an underscore are reserved, implementations may provide special semantics for such names. For example, the identifier
_BUILTIN_abs
could be used to indicate generation of in-line code for theabs
function. Thus, the appropriate header could specify#define abs(x) _BUILTIN_abs(x)
for a compiler whose code generator will accept it. In this manner, a user desiring to guarantee that a given library function such as
abs
will be a genuine function may write#undef abs
whether the implementation’s header provides a macro implementation of
abs
or a built-in implementation. The prototype for the function, which precedes and is hidden by any macro definition, is thereby revealed also.
请特别注意脚注 185 的内容。
您还引用了来自 §7.21.7.5 的 getc
定义中的 Material :
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.
(其中 stream
是用于 getc
的参数的名称。)
你问(稍微解释一下):
getc
的定义是否与库函数的定义相矛盾?
没有。 §7.1.4 开头说'除非明确说明',然后给出一系列通用规则,然后getc
的规范明确说明否则。
反之亦然吗?
没有。 §7.1.4 的开头部分说任何特定函数的规范都可以覆盖 §7.1.4 中的一般性规定。
这是否与标准不一致?
我看不出这里有什么矛盾。
或者这是否意味着如果 getc
仅作为宏实现(这似乎不符合要求但是……),宏可能会对其参数求值两次?
getc
不能单独实现为宏(脚注 185)。还必须有一个实现相同功能的实际函数。实现可以很简单:
int (getc)(FILE *fp) { return getc(fp); }
明确允许实现 getc
的宏对其参数求值多次(但不是必须这样做)。 §7.21.7.5 中的规范明确表示可以,而 §7.1.4 中的规范明确表示允许 §7.21.7.5 更改通常禁止此类行为的 §7.1.4 的一般规则。
关于c - getc() 作为宏和 C 标准库函数定义,连贯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39793885/
根据“未定义行为”的现代解释,编译器有权假设不会发生导致未定义行为“不可避免”的事件链,并且可以消除仅适用于以下情况的代码:将执行未定义的行为;这可能会导致未定义行为的影响及时倒退,并使原本可以观察到
在阅读 getc 手册页时,我遇到了: may be implemented as a macro which evaluates stream more than once. 那么,getc 也可以
程序有什么问题? #include #include #include main( ) { char * buf="robot.c"; char c;int i=0; FILE*f
在下面的代码中,我尝试存储文件中的所有字符(包括换行符)。如果读取换行符,变量“i”应该递增,“j”重置为 0,但这种情况不会发生。通过从我的数组打印到控制台,我已经确认换行符实际上正在被读取和存储。
它只是一个程序,我试图读取文件中作为参数传递的单词的出现次数,该文件也作为下一个参数传递。 代码如下所示: #include extern void exit(int); void main(int
我正在用 C 开发一个链表。我正在从一个 txt 文件中获取数据。但是当我尝试运行该程序时,它给我一个 getc() 的段错误这是代码, #include #include struct node{
程序: #include #include char *f_gets(char *s, int n, FILE *iop) { int c=0; char *cs; cs =
我试图找到 getc 和 fgetc 之间的区别。当时我看到这样的说法: The difference between getc and fgetc is that getc can be imple
我正在使用 Perl 6 模块 Term::termios . #!/usr/bin/env perl6 use v6; use Term::termios; my $saved_termios :=
我有一个函数读取 unsigned long long 中的每一位并将值存储在数组中,现在我想将此函数转换为返回数字中的下一位并将数据处理留给调用者的函数. 理想情况下,它的工作方式与 getc()
我有一个函数读取 unsigned long long 中的每一位并将值存储在数组中,现在我想将此函数转换为返回数字中的下一位并将数据处理留给调用者的函数. 理想情况下,它的工作方式与 getc()
我有一个函数 getNum(),它从文件中获取一个数字并返回它。当我回到 getNum() 时,我丢失了指针,它再次从文件的开始处开始。我想知道如何获取 getc 所在的位置,然后返回到那个地方。我在
所以我开始实现霍夫曼树,为此,我尝试从标准输入或输入文件获取字符值。输入文件(只是一个字符串“cheese”)被添加到数组 freqcounts 中,其中添加的 freqcounts 索引是它读取的字
我遇到的问题是在这一行: int tok = getc(fp); getc 返回 -1。为什么?提前致谢。 #include #include #include "file_reader.h" /
printf("hello2"); int i = 0; int done = 0; while (!done) { char c; printf("hello3"); c =
我正在阅读 Jim Trevor 等人所著的Cyclone:C 的安全方言。一切都是为了编程语言类(class)。作者表示,如果调用 getc(null) 可能会导致段错误,因为 C 标准没有指定如何
当我尝试从名为“file1”的文件中读取输入时,我的程序正确显示文件中的字符数,但采用无法识别的字符格式。下面是代码 #include #include void db_sp(FILE*); in
// Program to remove the comments and the spaces from the given input file #include #include using
这是我的代码。 #include #include int main(int argc,char** argv) { char a; a=9; FILE * fp; f
我正在尝试用 C 编写一个简单的“猫”克隆。我正在运行 Windows 7 并使用 MinGW 编译器。但是,每当我运行该程序时,它都会返回文本文件,但每个字符都替换为“☺”字符。提前谢谢你。 #in
我是一名优秀的程序员,十分优秀!