2012-04-09 68 views
0

在学校是我经常教导预处理语句可以很容易就会失控,因为你定义字符串,如:C++:contst静态DEBUG和if语句,实际执行时间开销是多少?

#define PI 3.1415926 

的地方在代码中的每个取代,导致怪异换人当一个变量名中包含字符串PI

因此,在调试的时候,我从以下途径引导远:

#define _DEBUG 
... 
#ifdef _DEBUG 
    // debug code 
#endif 
... 

但因子评分这将是“安全”的使用方法:

const static bool DEBUG = true 
int main() 
{ 
    ... 
    if(DEBUG){ /* debug code*/ } 
    ... 
} 

这种运作良好,但我不知道是什么,与预处理器语句方法相比,这种方法的运行时间是多少?使用预处理器方法,在编译之前,所有事情都会发生,所以不会出现运行时间开销。

我知道一个简单的if -statement的开销几乎可以忽略不计,但是当它深入到一些嵌套的循环运行很多次的时候,这并不适用(小的东西加起来大事)。

该编译器承认一个事实DEBUGconst static硬编码到这个可执行文件,已经启用或禁用在编译时的调试代码?是什么让我怀疑这是有一天,在编写一些不相关的代码时,编译器警告我关于代码的一部分已经过时,因为围绕它的if-状态永远不会成为现实(如果我没有记错的话)。

回答

3

这是不可能给出一个硬性保证:每个单独的编译器要对它提供的代码做什么。

但是,任何现实世界的编译器都会为您优化这一点。它是最简单,最平凡的优化之一,即使您禁用了优化,大多数编译器也可能会这样做。

它只是没有意义的生成的代码实质上是if (true)

所以在运行时应该有零开销。

3

标准中没有什么说编译器不能完全省略一段代码,如果它可以静态地(在编译时)确定它永远不会运行。

另一方面,标准中没有任何内容表示编译器必须会执行该优化(通常情况下)。所以如果你给你的编译器足够的信息,并打开它的优化特性,那么很可能它会完全消除这些分支。但唯一确定的方法是查看生成的代码。对于像那样的“微不足道”的调试启用代码,大多数现代编译器都会在大多数情况下完全消除死区。

+0

你是第一个!谢谢。我怀疑这件事,但很想知道。 – romeovs 2012-04-09 13:20:12

+0

(jalf第一个发帖) – Mat 2012-04-09 13:20:56

+0

呵呵,它说你早一分钟...奇怪 – romeovs 2012-04-09 14:47:41

1

在学校是我经常教导预处理语句可以很容易就会失控,因为你定义字符串,如:

的#define PI 3.1415926

的每一个地方取代在你的代码,从而导致当一个变量名包含字符串PI

不,PI替代仅在整个字(令牌)PI,不内的另一个令牌怪异取代。例如。 myPI不扩大PI

+0

是的,我经过一些测试后发现了这个。不知道老师为什么这么说(或者当时我误解了)。 – romeovs 2012-04-09 14:48:27

0

这是一个细节,但由于DEBUG现在是一个常量布尔,你应该用小写字母写:

const static bool debug = true; 

大写的名字被保留到预处理宏。