2010-06-08 57 views
1

在xcode中,当使用gcc编译应用程序时,如果NSZombieEnabled之类的东西在分发版本上运行,我想抛出编译时间错误,从而确保编译失败,不小心做了一些愚蠢的事情。如何在GCC和Xcode中手动抛出编译器错误

我做了一些Google搜索,但无法弄清楚如何在符合某些条件时让编译器保释。当然,它一定很容易,我只是没有找到它?

回答

11

使用the #error directive

#if SHOULD_FAIL 
#error "bad compiler!" 
#endif 

int main() 
{ 
    return 0; 
} 
 
$ gcc a.c -DSHOULD_FAIL=0 # passes fine 
$ gcc a.c -DSHOULD_FAIL=1 
a.c:2:2: error: #error "bad compiler!" 

由于NSZombieEnabled是一个环境变量,你需要做一些聪明的你构建脚本来定义宏为0或1。

严格地说,#error指令发生在C预处理器中,而不是gcc。但在你描述的情况下,这应该不重要。

+0

这似乎很难...似乎无法找到方法 – coneybeare 2010-06-08 03:07:29

+0

@coneybeare:NSZombieEnabled是您在**运行时设置的环境变量**。在编译时你不必担心它。但是,如果您有编译时调试宏,此技术很有用。 – JeremyP 2010-06-08 07:34:19

+0

+1请注意,你也可以做'#警告这是一个警告'发出警告而不是错误。 – 2010-06-19 15:23:29

1

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

0

你可以做另一个有趣的事情是操纵你的编译器的输出脚本。如果您正在使用自定义构建脚本作为构建过程的一部分,你可以这样做:

echo "error: this build step failed!" 

或者:

echo "warning: this build step could be potentially faulty" 

那些会产生(分别)错误或警告,将显示在构建结果窗口中打开。我已经使用了几次,并且它的确很有用

1

complile-time assert() - a.k.a。静态断言 - 可能会有所帮助。这里是我的,从http://www.pixelbeat.org/programming/gcc/static_assert.html主要衍生:

/*----------------------------------------------------------------------------- 
* 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)} 

但我纠正了在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)]