预处理C代码

时间:2017-02-03 19:46:39

标签: c

编译C程序时,我在预处理步骤中出错。

奇怪的是,我可以使用以下命令运行预处理,没有错误或警告:

gcc -I/usr/local/libpng-1.6.24/include -Wall -std=c99 lines.c -E -o lines

但使用下面的表单会给我错误:

cpp -I/usr/local/libpng-1.6.24/include -std=c99 lines.c -o lines

我假设cpp是作为gcc的一部分运行的,这使得它更加奇怪。

有关信息,请参阅下面我得到的错误 - 只有其中一个,我有很多同类的错误:

In file included from lines.c:1:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:65:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/Availability.h:172:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/AvailabilityInternal.h:15284:10: error:
    unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11

不用注意带错误的文件是Apple标准文件。我还必须说,似乎所有人都可以终止#endif匹配他们的#if指令

知道这里会发生什么吗?或者前进以追踪错误?

PS顺便说一下,我在OSX中使用Apple标准提供的开发人员工具运行它。

-

添加其他信息作为对某些评论的回复:

lines.c https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-s096-introduction-to-c-and-c-january-iap-2013/final-project/starter-kit/lines.c的源代码,并且有更多关于源代码使用位置的上下文,您可能希望在此处看到https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-s096-introduction-to-c-and-c-january-iap-2013/final-project/starter-kit/

如果我在没有-E选项的情况下运行gcc,实际上由于我的文件夹结构而出现了链接问题,但是下面的命令没有错误 - 但我不认为这些信息与问题相关,因为我想比较比如喜欢和选项-E在预处理后停止,而cpp只进行预处理:

gcc -I/usr/local/libpng-1.6.24/include -L/usr/local/libpng-1.6.24/lib -Wall -std=c99 lines.c -lpng -o lines

-

我已将我的Xcode从7.3升级到8.2.1,命令行工具从Command_Line_Tools_OS_X_10.11_for_Xcode_7.3升级到Command_Line_Tools_macOS_10.12_for_Xcode_8.2,gcc继续工作,cpp仍然触发错误。那么这个时候错误会有所改变。见下文

In file included from lines.c:1:
In file included from /usr/include/stdio.h:65:
In file included from /usr/include/Availability.h:184:
/usr/include/AvailabilityInternal.h:20265:10: error: #else without #if
    #else
/usr/include/AvailabilityInternal.h:20832:10: error: unterminated conditional directive
    #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11_4

2 个答案:

答案 0 :(得分:1)

如评论中所述,我可以在我的macOS Sierra 10.12.3机器上使用XCode 8重现您的问题,得到(至少)20个错误,因此它会在20日停止。

源文件:

#include <stdio.h>
int main(void) { puts("Hi"); return 0; }

命令行和错误输出:

$ /usr/bin/cpp -v min.c -o min.c.out >/dev/null
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name min.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 274.2 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0 -fdebug-compilation-dir /Users/jleffler/soq -ferror-limit 19 -fmessage-length 110 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -traditional-cpp -o - -x c min.c
clang -cc1 version 8.0.0 (clang-800.0.42.1) default target x86_64-apple-darwin16.4.0
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
In file included from min.c:1:
In file included from /usr/include/stdio.h:65:
In file included from /usr/include/Availability.h:184:
/usr/include/AvailabilityInternal.h:20265:10: error: #else without #if
        #else
         ^
/usr/include/AvailabilityInternal.h:20832:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11_4
         ^
/usr/include/AvailabilityInternal.h:20765:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11_3
         ^
/usr/include/AvailabilityInternal.h:20702:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11_2
         ^
/usr/include/AvailabilityInternal.h:20643:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_11
         ^
/usr/include/AvailabilityInternal.h:20588:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10_3
         ^
/usr/include/AvailabilityInternal.h:20537:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10_2
         ^
/usr/include/AvailabilityInternal.h:20490:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10
         ^
/usr/include/AvailabilityInternal.h:20447:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9
         ^
/usr/include/AvailabilityInternal.h:20408:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8
         ^
/usr/include/AvailabilityInternal.h:20373:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_7
         ^
/usr/include/AvailabilityInternal.h:20342:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6
         ^
/usr/include/AvailabilityInternal.h:20315:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
         ^
/usr/include/AvailabilityInternal.h:20292:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_4
         ^
/usr/include/AvailabilityInternal.h:20273:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_3
         ^
In file included from min.c:1:
In file included from /usr/include/stdio.h:65:
/usr/include/Availability.h:233:2: error: #else without #if
#else
 ^
/usr/include/Availability.h:236:2: error: #endif without #if
#endif
 ^
/usr/include/Availability.h:272:2: error: #endif without #if
#endif
 ^
/usr/include/Availability.h:299:2: error: #endif without #if
#endif
 ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
$

请注意,我使用的唯一选项是-v(在开始时生成详细输出)和-o min.c.out(在详细输出中用-o -覆盖;它按照自己的意愿行事,而不是按照我的要求行事 - 真正排名不服从。因此,标准输出重定向到/dev/null是必要的,以避免看到所有输出。

如果我将/usr/bin/cpp替换为/usr/bin/gcc(由于gcc/opt/gcc/v6.2.0/bin/gcc,即GCC 6.2.0),我需要该路径,并添加{{ 1}}选项,它工作正常:

-E

这强烈暗示了$ /usr/bin/gcc -E -v min.c -o min.c.out Apple LLVM version 8.0.0 (clang-800.0.42.1) Target: x86_64-apple-darwin16.4.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name min.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 274.2 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0 -fdebug-compilation-dir /Users/jleffler/soq -ferror-limit 19 -fmessage-length 110 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o min.c.out -x c min.c clang -cc1 version 8.0.0 (clang-800.0.42.1) default target x86_64-apple-darwin16.4.0 #include "..." search starts here: #include <...> search starts here: /usr/local/include /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include /usr/include /System/Library/Frameworks (framework directory) /Library/Frameworks (framework directory) End of search list. $ wc -l min.c.out 456 min.c.out $ 程序中的某种问题及其驱动编译工具链其余部分的方式,但我没有在命令行中找出关键区别。

它还暗示了一个解决方案 - 不要单独使用/usr/bin/cpp。正如我在评论中指出的那样,2017年1月有一个问题 - How to get XCode 8 C preprocessor to ignore // comments in #defines?也指出了独立cpp中的问题。

如果您必须有效cpp,请安装自己的cpp。例如,您可以在某个位置(例如/opt/gcc/v6.3.0/bin/cpp)安装GCC 6.3.0(我在这台机器上一直很懒;我的另一台已经运行6.3.0,而不是6.2.0),然后安排键入/usr/bin/cpp时要运行而不是cpp - 调整PATH,或将符号链接或脚本放在/usr/local/bin$HOME/bin等目录中在PATH之前/usr/bin发生,或在makefile中指定正确的PATH,或者在其中指定正确的PATH。

如果您需要在Mac上构建GCC的指南,请考虑:

答案 1 :(得分:0)

我的Mac上似乎与user2353698或Jonathan Leffler没有完全相同的AvailabilityInternal.h,但我仍然可以重现这个问题:

$ /usr/bin/cpp -w /usr/include/AvailabilityInternal.h > /dev/null
/usr/include/AvailabilityInternal.h:14923:10: error: #else without #if
        #else
         ^

在疯狂方便delta utility的帮助下,我将其缩减为最小化的测试用例:

#ifndef foo
    #ifdef bar
    #endif
#endif

这是完全合法的标准 C,但传统的(K&amp; R)预处理器不会将任何缩进行理解为预处理指令。 clang对传统预处理模式的仿真似乎有一个错误,其中缩进的#ifdef 处理但缩进的#endif 处理的,所以随后的非缩进#endif似乎不平衡。 (在gcc -E -traditional-cpp实际为GCC的计算机上比较此文件gcc的行为。)现在报告为LLVM bug #31886

我昨天在评论中所说的仍然是正确的:如果你想预处理标准C,请使用cc -E。即使没有此错误,cpp也无法在这些系统标头上提供正确的结果。 故意 cpp使用传统模式,因为现在该命令行工具的主要功能是预处理非C 的事物,例如FORTRAN, Makefile和X资源文件。传统的预处理器更适合这项任务,因为它不像C的词法语法那样专门。