GCC中的-D__USE_FIXED_PROTOTYPES__用于什么?

时间:2018-01-01 09:02:42

标签: c unix gcc makefile

在书Practical C Programming第7章编程过程中,有一个makefile:

File: calc1/makefile.gcc
#-----------------------------------------------#
#   Makefile for unix systems       #
#    using a GNU C compiler         #
#-----------------------------------------------#
CC=gcc
CFLAGS=-g -D__USE_FIXED_PROTOTYPES__ -ansi
#
# Compiler flags:
#   -g  -- Enable debugging
#   -Wall   -- Turn on all warnings (not used since it gives away
#           the bug in this program)
#   -D__USE_FIXED_PROTOTYPES__
#       -- Force the compiler to use the correct headers
#   -ansi   -- Don't use GNU extensions.  Stick to ANSI C.

calc1: calc1.c
    $(CC) $(CFLAGS) -o calc1 calc1.c

clean:
    rm -f calc1 

什么是“正确的标题”?为什么选项参数 -D __ USE_FIXED_PROTOTYPES __ 之间没有空格?

GCC mirror中,有:

/* __USE_FIXED_PROTOTYPES__ used to be required to get prototypes for
   malloc, free, etc. on some platforms.  It is unclear if we still
   need it, but it can't hurt.  */
#define __USE_FIXED_PROTOTYPES__

Re: Is __USE_FIXED_PROTOTYPES__ really necessary?有解释。

但我没有得分。

这本PRACC书出版于1997年,有点陈旧但仍然非常有用。 Makefile有点过时,我想知道是否需要.gcc扩展名。

Errata for Practical C Programming中没有提到这些。

1 个答案:

答案 0 :(得分:5)

所有这一切都是错误的。我不知道在2011年最新修订版出版年后的第7年,迫使编制者坚持在2018年 201 中弃用的1989年标准修订版的实用性。

似乎已经讨论了__USE_FIXED_PROTOTYPES__的必要性in 1997。它是使代码在头文件早于1989标准的平台上运行。你不需要它。那时你可以有一个程序执行以下操作:

#include <stdlib.h>
int main() {
    void *p = malloc(42.0);
}

程序会有未定义的行为,因为<stdlib.h>不会包含原型,而且参数类型错误。

现在海湾合作委员会并没有这样做。自C99以来,如果缺少原型,海湾合作委员会将大声抱怨。它也会抱怨错误的参数类型等:

// #include <stdlib.h>
int main() {
    void *p = malloc(42.0);
}

编译时:

% gcc test.c 
test.c: In function ‘main’:
test.c:2:15: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
     void *p = malloc(42.0);
               ^~~~~~
test.c:2:15: warning: incompatible implicit declaration of built-in function ‘malloc’
test.c:2:15: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’

使用-pedantic-errors隐式函数声明会成为导致编译失败的错误(应该如此)。

我甚至不确定这现在是否真的有效。据推测,这是为了修复声明,以便每当你包含<stdlib.h>时,它也意味着例如malloc将具有正确的原型,而不是隐含的函数声明。 20年前编制15年前的系统可能是相关的。现在,在为35岁的系统进行编译时,它是相关的。

如果这是本书提供的实用建议,我的实际建议是将其用作燃烧过程的燃料。这可能是你用它做的最有用的事情。

如果您重视标准符合性,请使用

而不是所有这些标志
-Wall -std=c11 -pedantic-errors

如果没有-pedantic-errors,即使-std=c11 -Wall也会允许某些GCC特定扩展名漏掉。