我有一些像这样的预处理器代码:
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#if GCC_VERSION < 40503
#error Your compiler is outdated.
#error You need at least gcc 4.5.3 for this library.
#error You have: GCC_VERSION
#error You have: STR(GCC_VERSION)
#endif
但是我尝试输出当前编译器版本的两种方式都失败了。根据{{3}},这是因为
'#error'和'#warning'都没有扩大其论点。内部空白序列每个都用一个空格替换。该行必须包含完整的令牌。最明智的做法是使这些指令的参数为单个字符串常量;这避免了撇号等问题。
如何输出带有错误消息的编译器版本?是否有任何预处理器魔法可以让我实现这个目标?
答案 0 :(得分:1)
如果#error
没有扩展其论点,我会采取务实的方法:
#if GCC_VERSION < 40503
#error Outdated compiler < 4.5.3, run 'gcc --version' to get version.
#endif
我能想到的另一个可能性是使用自己的预处理器预处理文件,用{{1}中提取的内容替换(例如)xyzzy_GCC_VERSION_plugh
的所有出现}。
无论如何,要做很多努力和维护工作是不必要的。
但是,如果真的想要这样做,你可以使用类似的东西:
gcc --version
并且您的actual=$(echo "GCC_VERSION" | gcc -E - | tail -1)
sed "s/xyzzy_GCC_VERSION_plugh/$actual/g" file1.c >file1_morphed.c
gcc -c -o file1.o file1_morphed.c
将包含在某个位置的顶部:
file1.c
但是,正如我所说,这对于没有多少好处的工作是相当有意义的。我的建议只是告诉使用你的库的人如何自己获得编译器版本。毕竟他们是开发人员,我希望他们能够处理这样的指令。
答案 1 :(得分:1)
此问题的经典“解决方案”是设法生成包含所需消息的错误。例如:
#define S(x) #x
#define STR(x) S(x)
#if GCC_VERSION < 40503
#error Outdated compiler: you need at least gcc 4.5.3 for this library.
#define above_message_indicates_installed_gcc_version STR(Installed GCC version: GCC_VERSION)
#include above_message_indicates_installed_gcc_version
#endif
虽然这确实提供了一些信息,但它仍然会被误解;就个人而言,我认为让开发人员知道所需的最低版本就足够了。
答案 2 :(得分:0)
结合paxdiablo的提议和static compile time assertions的想法,我决定采用以下解决方案。
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#define ERROR_MESSAGE(major, minor, patchlevel) compiler_version__GCC_ ## major ## _ ## minor ## _ ## patchlevel ## __ ;
#define OUTDATED_COMPILER_ERROR(major, minor, patchlevel) ERROR_MESSAGE(major, minor, patchlevel)
#if GCC_VERSION < 40503
#error Outdated compiler version < 4.5.3
#error Absolute minimum recommended version is avr-gcc 4.5.3.
#error Use 'avr-gcc --version' from the command line to verify your compiler version.
#error Arduino 1.0.0 - 1.0.6 ship with outdated compilers.
#error Arduino 1.5.8 (avr-gcc 4.8.1) and above are recommended.
OUTDATED_COMPILER_ERROR(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#endif