Iphone 如何在GCC和Xcode中手动抛出编译器错误

Iphone 如何在GCC和Xcode中手动抛出编译器错误,iphone,objective-c,xcode,gcc,compiler-construction,Iphone,Objective C,Xcode,Gcc,Compiler Construction,在xcode中,当使用gcc编译应用程序时,如果发行版中启用了NSZombieEnabled之类的功能,我希望抛出编译时间错误,从而确保编译将失败,并且我不会意外地做一些愚蠢的事情 我在谷歌上搜索了一下,但不知道如果满足某个条件,如何使编译器退出。当然这一定很容易,难道我找不到它吗?使用: $gcc a.c-D应为0#合格 $gcc a.c-D应为1 a、 c:2:2:error:#error“bad compiler!” 由于NSZombieEnabled是一个环境变量,您需要在构建脚本中做一

在xcode中,当使用gcc编译应用程序时,如果发行版中启用了NSZombieEnabled之类的功能,我希望抛出编译时间错误,从而确保编译将失败,并且我不会意外地做一些愚蠢的事情

我在谷歌上搜索了一下,但不知道如果满足某个条件,如何使编译器退出。当然这一定很容易,难道我找不到它吗?

使用:

$gcc a.c-D应为0#合格 $gcc a.c-D应为1 a、 c:2:2:error:#error“bad compiler!” 由于
NSZombieEnabled
是一个环境变量,您需要在构建脚本中做一些巧妙的事情,将宏定义为零或一


严格地说,
#error
指令出现在C预处理器中,而不是
gcc
。但这在您描述的情况下并不重要。

NSZombieEnabled
是一个环境标志,据我所知,它不应该影响生成的二进制文件(尽管它可能会影响编译速度)。

您可以做的另一件有趣的事情是操纵构建脚本的输出。如果在构建过程中使用自定义构建脚本,可以执行以下操作:

echo "error: this build step failed!"
或:

这些将分别产生错误或警告,并显示在“生成结果”窗口中。我已经使用过几次了,它非常有用。

一个complile time assert()--也称为static assert--可能会有帮助。这是我的,主要来源于:

但我纠正了我对C++0x中“无用”消息的看法:

/*-----------------------------------------------------------------------------
 *  Correction!: The message in static_assert() isn't quite useless, and we've
 *  added it to ASSERTM(). This is needed for the case where two different
 *  header files happen by chance to have two ASSERT()'s on the same line, or
 *  likewise for a source file and a header file.
 *
 *  We could also handle this via __COUNTER__, but this isn't supported by
 *  the SGI compiler (and is uglier). And we can't use __FILE__, because it
 *  doesn't usually expand to a valid C token (e.g. it has a dot c or dot h).
 */
#define ASSERTM(e,m) enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}
一些例子:

/*-----------------------------------------------------------------------------
 *  Example:
 */
ASSERTM (sizeof (int16) == 2, my_global_header_h);
ASSERTM (sizeof (ord32) == 4, my_global_header_h);
ASSERTM (sizeof (int64) == 8, my_global_header_h);

/*-----------------------------------------------------------------------------
 *  Equally good, I believe, is the following variant, but it is slightly
 *  longer (and not used by us at the present time):
 */
#define ASSERTt(e) typedef int EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__)[1-2*!(e)]

这似乎很难…似乎找不到解决方案way@coneybeare:NSZombieEnabled是您在运行时设置的环境变量。您不需要在编译时担心它。但是,如果您有编译时调试宏,此技术非常有用。+1请注意,您也可以执行
#警告这是发出警告而不是错误的警告。
echo "warning: this build step could be potentially faulty"
/*-----------------------------------------------------------------------------
 *  Compile-time ASSERT(). Similar to the BOOST_STATIC_ASSERT(). And the C++0x
 *  static_assert(), which also has a parameter for a useless error message
 *  (see correction!). Our ASSERT() can be placed anywhere in the code, except:
 *
 *  o In a twice-included header file, without a #ifndef...#endif wrapper.
 *  o In the middle of a structure definition (or enum definition).
 *  o In C89 or C90, after a statement. But you can wrap it in braces!
 *
 *  If you want stick something in the middle of a structure definition
 *  you'll need to use the ugly, three-line construct #if...#error...#endif.
 *  And if you do do this, the pre-processor has a much more limited idea of
 *  what a "constant expression" is.
 *
 *  This is a refinement of ideas from the web (www.pixebeat.org is good). It
 *  is shorter than BOOST. And, I believe, is better than Linus Torvald's
 *  suggestion for an improved BUILD_BUG_ON(). And the do{...}while(0) wrapper
 *  you commonly see is totally inapplicable here: it limits permissible
 *  locations.
 *
 *  The web has many suggestions using arrays with a negative index. But with
 *  GCC, most of these do not detect a NON-CONSTANT arg (which is easy enough
 *  to do in error), except for the attractive 'extern int foo[expression]',
 *  which also gives an 'unused variable' warning (which might be fixable via
 *  (void)foo). GCC 4.3 apparently has a built-in static_assert(). Update:
 *  typedef int array[expression] seems also to be good.
 */
#define CONCAT_TOKENS(a, b) a ## b
#define EXPAND_THEN_CONCAT(a,b) CONCAT_TOKENS(a, b)
#define ASSERT(e) enum {EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__) = 1/!!(e)}
/*-----------------------------------------------------------------------------
 *  Correction!: The message in static_assert() isn't quite useless, and we've
 *  added it to ASSERTM(). This is needed for the case where two different
 *  header files happen by chance to have two ASSERT()'s on the same line, or
 *  likewise for a source file and a header file.
 *
 *  We could also handle this via __COUNTER__, but this isn't supported by
 *  the SGI compiler (and is uglier). And we can't use __FILE__, because it
 *  doesn't usually expand to a valid C token (e.g. it has a dot c or dot h).
 */
#define ASSERTM(e,m) enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}
/*-----------------------------------------------------------------------------
 *  Example:
 */
ASSERTM (sizeof (int16) == 2, my_global_header_h);
ASSERTM (sizeof (ord32) == 4, my_global_header_h);
ASSERTM (sizeof (int64) == 8, my_global_header_h);

/*-----------------------------------------------------------------------------
 *  Equally good, I believe, is the following variant, but it is slightly
 *  longer (and not used by us at the present time):
 */
#define ASSERTt(e) typedef int EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__)[1-2*!(e)]