2

Is it possible to put #ifndef at the top of a c file? Basically I need to check whether a certain preprocessor constant was declared when running the program and my program will change accordingly.

I need to check if -D DESCENDING_ORDER=1 is added as an argument (doesn't matter what value given).

I have this code at the top of my main c file:

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

Works when compiling by itself, but I get errors when I try compiling with a Makefile, something along the lines of "expected identifier before 'int' for int ascending = 1.

Thanks.

EDIT - Added Makefile code

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

Kind of guessed and added $(INC)....DESCENDING_ORDER=1 to the end of the command, so that's probably why it's not working. Command I'm using without makefile:

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

EDIT 2 - Had a little play with different arguments and found that I get the same error if I remove -include res.h in the command. Still not sure how to correctly reference the header file in the makefile? I've added the #include "res.h" in my res.c file but still get the error.

4

2 回答 2

3

Makefile你的since $(CLAGS)should be中有一个错字$(CFLAGS)。了解更多关于 的信息make,特别是通过运行make -p它向您显示许多内置规则make并使用它们(例如考虑使用$(COMPILE.c)$(LINK.c)

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

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

标准做法是:

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

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

  • 将您Makefile对相关目标文件的依赖项添加到新的#include-d 文件中res.h;请注意,这些依赖项可以自动生成(通过传递例如-MDtogcc等...)

  • 通过-DDESCENDING_ORDER=1CFLAGS更好CPPFLAGS

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

附加物

您可能希望使用生成源代码的预处理形式,res.i并且可以有如下规则res.cgcc -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中的预处理是文本操作,而您的预处理形式是错误的。

顺便说一句,最近的 Clang/LLVM(3.2 版)或 GCC(刚刚发布的 4.8 版)编译器为您提供了更好的关于预处理的消息。

于 2013-03-23T08:10:37.970 回答
0

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

于 2013-03-23T07:46:03.383 回答