c文件中的#ifndef?

时间:2013-03-23 07:43:54

标签: c header c-preprocessor

是否可以将#ifndef放在c文件的顶部?基本上我需要检查在运行程序时是否声明了某个预处理器常量,我的程序会相应地改变。

我需要检查是否添加了-D DESCENDING_ORDER=1作为参数(与给定的值无关)。

我的代码位于主c文件的顶部:

#ifndef DESCENDING_ORDER
int ascending = 1;
#else
int ascending = 0;
#endif

在自行编译时工作,但是当我尝试使用Makefile进行编译时遇到错误,类似于int ascending = 1的'int'之前的预期标识符。

感谢。

编辑 - 添加了Makefile代码

CC=gcc
CFLAGS=-g -Wall
INC=-include
RES_OBS=res.o
LIBS=
all: res

res:    $(RES_OBS)

    $(CC) $(CFLAGS) -o res $(RES_OBS) $(LIBS) $(INC) res.h -D DESCENDING_ORDER=1

clean:
        rm -f *.o

clobber:
        make clean
        rm -f res

猜测并在命令末尾添加了$(INC)....DESCENDING_ORDER=1,这可能就是为什么它不起作用了。 命令我没有使用makefile:

gcc res -include res.h -D DESCENDING_ORDER=1

编辑2 - 玩了不同的参数,发现如果我在命令中删除-include res.h,我会得到同样的错误。仍然不确定如何正确引用makefile中的头文件?我在我的res.c文件中添加了#include "res.h",但仍然收到错误。

2 个答案:

答案 0 :(得分:3)

由于Makefile $(CLAGS) $(CFLAGS)make中存在拼写错误。  详细了解make -p,特别是通过运行make$(COMPILE.c)展示许多内置规则并使用它们(例如考虑使用$(LINK.c)和{{1}等等。)

不要忘记将-Wall添加到CFLAGS,因为您需要编译器发出的所有警告。您可能也想要调试信息,因此也要添加g

在Linux上,我建议使用remake来调试Makefile - s通过运行remake -x来帮助很多。

标准做法是:

  • 避免将-include传递给gcc,而是在相关#include "res.h"源文件的开头附近添加*.c

  • -D粘贴到定义的符号,例如-DDESCENDING_ORDER=1

  • Makefile相关对象文件的相关性添加到新#include - d文件res.h;请注意,这些依赖关系可以自动生成(例如将-MD传递给gcc等等......)

  • 通过-DDESCENDING_ORDER=1CFLAGS或更好CPPFLAGS

不要忘记gcc的程序参数顺序很重要。

附加物

您可能希望使用res.i生成源代码res.c的预处理表单gcc -C -E,您可以使用

这样的规则
  res.i: res.c res.h
           $(CC) -C -E $(CFLAGS) $(CPPFLAGS) $^ -o $@

然后执行make res.i并使用某个编辑器或寻呼机(可能less)检查预处理器输出res.i;或者,在命令行上执行此操作

  gcc -C -E -I. -DDESCENDING_ORDER=1  res.c | less

您可以删除生成的行信息并执行

  gcc -C -E -I. -DDESCENDING_ORDER=1  res.c | grep -v '^#' > res_.i
  gcc -Wall -c res_.i

关键是 C 中的预处理是文本操作,而您的预处理表单是错误的。

BTW最近的Clang / LLVM(版本3.2)或GCC(刚刚发布的版本4.8)编译器为您提供了更好的预处理消息。

答案 1 :(得分:0)

代码很好。使用Makefile时遇到的错误与其他事情有关(如果没有看到#ifndef之前的内容并看到Makefile,很难确定。)