Ssu*_* Yu 3 c unix gcc makefile
在实用C编程,第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
Run Code Online (Sandbox Code Playgroud)
什么是"正确的标题"?为什么选项参数-D和__USE_FIXED_PROTOTYPES__之间没有空格?
在GCC镜像中,有:
/* __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__
Run Code Online (Sandbox Code Playgroud)
来自Re的__USE_FIXED_PROTOTYPES__解释:真的有必要吗?.
但我不明白这一点.
这本PRACC书出版于1997年,有点陈旧但仍然非常有用.Makefile有点过时,我想知道是否需要.gcc扩展名.
在实践C编程勘误表中没有提到这些.
所有这一切都是错误的.我不知道在2011年最新修订版出版年后的第7年,迫使编制者坚持2018年被废弃的1989年标准修订版是多么可行.
__USE_FIXED_PROTOTYPES__似乎已经在1997年讨论了必要性.它是使代码在头文件早于1989标准的平台上工作.你不需要它.那时你可以有一个程序执行以下操作:
#include <stdlib.h>
int main() {
void *p = malloc(42.0);
}
Run Code Online (Sandbox Code Playgroud)
并且程序将具有未定义的行为,因为它<stdlib.h>不包含原型,并且参数的类型错误.
现在海湾合作委员会不会那样工作.自C99以来,如果缺少原型,海湾合作委员会将大声抱怨.它还会抱怨错误的参数类型等:
// #include <stdlib.h>
int main() {
void *p = malloc(42.0);
}
Run Code Online (Sandbox Code Playgroud)
编译时:
% 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’
Run Code Online (Sandbox Code Playgroud)
使用-pedantic-errors隐式函数声明会成为导致编译失败的错误(应该如此).
我甚至不确定这现在是否真的有任何影响.据推测,这是为了修复声明,以便每当你包含<stdlib.h>它时也意味着例如malloc会有一个正确的原型,而不是隐含的函数声明.20年前编制15年前的系统可能是相关的.现在,在为35岁的系统进行编译时,它是相关的.
如果这是本书提供的实用建议,我的实际建议是将其用作燃烧过程的燃料.它可能是你可以做的最有用的事情.
如果您重视标准一致性,请使用,而不是所有这些标志
-Wall -std=c11 -pedantic-errors
Run Code Online (Sandbox Code Playgroud)
没有-pedantic-errors,甚至-std=c11 -Wall会允许一些GCC特定扩展漏掉.