#define 在文件加载之间被清除?

#define getting cleared between file loads?

我正在开发一些开源代码;我有一个 configure.ac,我在其中添加了以下内容:

: ${FFT_MODE=1}
AC_ARG_VAR([FFT_MODE], [1 for fftw3, 2 for kiss_fft])
AC_DEFINE_UNQUOTED([FFTMODE], [$FFT_MODE],
                   [1 for fftw3, 2 for kiss_fft])

想法是(在调用 autoconf --install 之后),用户可以 运行 例如./configure FFT_MODE=2 切换模式。现在,我 认为 它正在工作 - 配置文件末尾的状态检查输出正确的值,并且我代码中的 if/elif/endif 显示正确的块正在执行。然而 - 在某些时候我添加了一个 else,并发现 ifelse 块都是 运行ning。起初我以为我的编译器被附身了,然后我意识到文件被加载了两次,第二次,出于某种原因,FFTMODE 未设置(或设置为零或其他)。不过,我不明白怎么做。 FTR,检查在文件 fsk.h 中,如下所示:

#warning before
#if(FFTMODE == 1)
#warning FFTMODE 1
#include <fftw3.h>
#elif(FFTMODE == 2)
#warning FFTMODE 2
#include <kiss_fftr.h>
#else
#warning FFTMODE ???
#error Unsupported FFTMODE
#endif
#warning after

make的输出如下:

make  all-recursive
make[1]: Entering directory '/home/erhannis/mods/minimodem'
Making all in src
make[2]: Entering directory '/home/erhannis/mods/minimodem/src'
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT minimodem.o -MD -MP -MF .deps/minimodem.Tpo -c -o minimodem.o minimodem.c
In file included from minimodem.c:43:
fsk.h:20:2: warning: #warning before [-Wcpp]
   20 | #warning before
      |  ^~~~~~~
fsk.h:22:2: warning: #warning FFTMODE 1 [-Wcpp]
   22 | #warning FFTMODE 1
      |  ^~~~~~~
In file included from minimodem.c:43:
fsk.h:31:2: warning: #warning after [-Wcpp]
   31 | #warning after
      |  ^~~~~~~
mv -f .deps/minimodem.Tpo .deps/minimodem.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT databits_ascii.o -MD -MP -MF .deps/databits_ascii.Tpo -c -o databits_ascii.o databits_ascii.c
mv -f .deps/databits_ascii.Tpo .deps/databits_ascii.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT databits_binary.o -MD -MP -MF .deps/databits_binary.Tpo -c -o databits_binary.o databits_binary.c
mv -f .deps/databits_binary.Tpo .deps/databits_binary.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT databits_callerid.o -MD -MP -MF .deps/databits_callerid.Tpo -c -o databits_callerid.o databits_callerid.c
mv -f .deps/databits_callerid.Tpo .deps/databits_callerid.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT databits_baudot.o -MD -MP -MF .deps/databits_baudot.Tpo -c -o databits_baudot.o databits_baudot.c
mv -f .deps/databits_baudot.Tpo .deps/databits_baudot.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT baudot.o -MD -MP -MF .deps/baudot.Tpo -c -o baudot.o baudot.c
mv -f .deps/baudot.Tpo .deps/baudot.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT databits_uic.o -MD -MP -MF .deps/databits_uic.Tpo -c -o databits_uic.o databits_uic.c
mv -f .deps/databits_uic.Tpo .deps/databits_uic.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT uic_codes.o -MD -MP -MF .deps/uic_codes.Tpo -c -o uic_codes.o uic_codes.c
mv -f .deps/uic_codes.Tpo .deps/uic_codes.Po
gcc -DHAVE_CONFIG_H -I. -I..  -D_REENTRANT  -Wall  -g -O2 -MT fsk.o -MD -MP -MF .deps/fsk.Tpo -c -o fsk.o fsk.c
In file included from fsk.c:30:
fsk.h:20:2: warning: #warning before [-Wcpp]
   20 | #warning before
      |  ^~~~~~~
fsk.h:28:2: warning: #warning FFTMODE ??? [-Wcpp]
   28 | #warning FFTMODE ???
      |  ^~~~~~~
fsk.h:29:2: error: #error Unsupported FFTMODE
   29 | #error Unsupported FFTMODE
      |  ^~~~~
fsk.h:31:2: warning: #warning after [-Wcpp]
   31 | #warning after
      |  ^~~~~~~
fsk.c: In function ‘fsk_bit_analyze’:
fsk.c:200:10: error: ‘mag_mark’ undeclared (first use in this function)
  200 |     if ( mag_mark > mag_space ) {
      |          ^~~~~~~~
fsk.c:200:10: note: each undeclared identifier is reported only once for each function it appears in
fsk.c:200:21: error: ‘mag_space’ undeclared (first use in this function)
  200 |     if ( mag_mark > mag_space ) {
      |                     ^~~~~~~~~
fsk.c:166:11: warning: unused variable ‘magscalar’ [-Wunused-variable]
  166 |     float magscalar = 2.0f / (float)bit_nsamples;
      |           ^~~~~~~~~
fsk.c: In function ‘fsk_detect_carrier’:
fsk.c:628:1: warning: control reaches end of non-void function [-Wreturn-type]
  628 | }
      | ^
make[2]: *** [Makefile:470: fsk.o] Error 1
make[2]: Leaving directory '/home/erhannis/mods/minimodem/src'
make[1]: *** [Makefile:361: all-recursive] Error 1
make[1]: Leaving directory '/home/erhannis/mods/minimodem'
make: *** [Makefile:302: all] Error 2

所以,这是怎么回事?在 config.h.in 中有一个 #undef FFTMODE 的实例——但是虽然我可以猜到该文件是在构建完成后清理的,但构建还没有完成,所以为什么它要清理定义我'我还在用吗?

源代码在https://github.com/erhannis/minimodem/tree/feature/alternate_fft;相关文件是 src/fsk.h.

我认为您对文件被加载两次的想法感到困惑。从您显示的输出来看,情况似乎并非如此。

相反,文件在两个不同的编译命令中各加载一次。一次编译 minimodem.c,一次编译 fsk.c。这些是完全不同的编译操作。

minimodem.c中,FFTMODE的值为1。在 fsk.c 中,FFTMODE 未设置。

这很容易解释:在 minimodem.c 中你 #include "config.h" 在你 #include "fsk.h" 之前,所以当 fsk.h 被解析时你有一个值 FFTMODE .在 fsk.c 中你没有 #include "config.h",所以 FFTMODE 没有价值。

如果您的 fsk.h 文件需要来自 config.h 的值,那么最好在 fsk.h#include "config.h"。如果你不想这样做,你需要确保它包含在所有 .c 文件中,在 fsk.h.

之前