Chinaunix首页 | 论坛 | 博客
  • 博客访问: 167506
  • 博文数量: 41
  • 博客积分: 445
  • 博客等级: 下士
  • 技术积分: 280
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-22 14:54
文章分类

全部博文(41)

文章存档

2015年(9)

2014年(7)

2013年(4)

2012年(21)

我的朋友

分类: C/C++

2015-01-19 10:30:36

#pragma与_Pragma  


#pragma与_Pragma

       C90为预处理指令家族带来一位新成员:#pragma。一般情况下,大家很少见到它。

       #pragma的作用是为特定的编译器提供特定的编译指示,这些指示是具体针对某一种(或某一些)编译器的,其他编译器可能不知道该指示的含义又或者对该指示有不同的理解,也即是说,#pragma的实现是与具体平台相关的。

       为了让大家了解#pragma的用法,这里暂时以HP C Compiler为例子。HP C编译器主要运行在HP-UX平台上,它的一般用法和gcc大致相同,例如要编译程序:

       $cc example.c

       如果我们明确指示编译器优化代码,可以这样编译:

       $cc +On example.c

       其中n可以是1、2、3、4,分别代表不同程度的优化,例如:

       $cc +O2 example.c

       这条命令指示HP C编译器对整个example.c的代码采取第2级别的优化编译。

       但是,某种情况下我们可能需要特殊对待某一部分的代码,譬如暂停优化,HP C编译器提供几种途径去实现,其中之一是使用#pragma:

       //prog.c

       void f(){...}

       #pragma OPTIMIZE OFF

       int g(){...}

       #pragma OPTIMIZE ON

       double h(){...}

       $cc +O2 prog.c

       上面的prog.c中有3个函数,我们想用第2级别的优化编译代码整个文件。惟独函数g()例外,我们出于某种考虑决定不对它进行任何优化,可以看到,用两条#pragma指令就能够达到目的。

       第一条#pragma指令指示编译器停止优化代码,于是g()的代码是没有经过优化的。第二条#pragma指令通知编译器重新开始代码的优化编译(优化级别仍然是先前命令行给出的level 2),所以从h() 开始的代码又都是经过优化的。

       这里以代码的优化编译为例简单介绍了#pragma的用法,读者必须记住:具体的#pragma指令在不同情况下可能有不同的效果。假设有两家厂商各自推出自己的C编译器,可能真会这么巧同时使用相同的#pragma指令,偏偏它们的实现又不相同,这样编译的代码就可能会出现意想不到的结果。所以,为了保证#pragma指令能够被正确的解释,我们通常需要利用其他的预处理指令给予配合,例如:

       ...

       #ifdef __hpux

              #pragma FLOAT_TRAPS_ON _ALL

       #endif

       ...

       上例中,只有定义“__hpux”宏的HP C编译器才会看到#pragma指令,其他编译器,例如gcc,根本不会看到它的,因为gcc不会去定义“__hpux”宏,所以早在预处理阶段,#pragma指令的内容就被预处理程序删掉了。

       有人可能会问:如果万一编译器看到它不认识的#pragma指令会报错吗?

       答案是:不会。

       具体到某一条#pragma指令的涵义不是C标准的管辖范围,编译器不能够因为看到不认识的#pragma指令就说程序有错,惟一的做法是忽略它。

       例如:

       /*Example C code*/

       #pragma UNKNOWN_DIRECTIVE UNKNOWN_OPTION

       int main(void)

       {

              return 0;

       }

       $gcc test.c

       $./a.out

       $

        尽管gcc不认识上面代码中的#pragma指令,但编译test.c是完全没有问题的。

       现在,C99提供新的关键字“_Pragma”完成类似的功能,例如:

       #pragma OPTIMIZE OFF

       在C99中可以写成:

       _Pragma(“OPTIMIZE OFF”)              //注意:语句后面是没有分号的

       “_Pragma”比“#pragma”(在设计上)更加合理,因而功能也有所增强。

       例如,我们的编译器支持4个不同程度的优化等级,如果使用#pragma,则这样写:

       #pragma OPT_LEVEL n //1≤n≤4

    你会不会觉得每次都要重复写“#pragma...”很麻烦?如果可以利用宏定义来简化书写就好了:

    #define OPT_L(x) #pragma OPT_LEVEL x

    这时我们只须写:

    OPT_L(3)

    就相当于写:

    #pragma OPT_LEVEL 3

    可惜,在C90里这永远是一个梦想!因为字符“#”在预处理指令中有特殊的用途,跟在它后面的必须是宏的参数名,例如:

    #define MACRO(x) #x

    那么,MACRO(example)的替换结果为:

    “example”

       可以想象,前面通过#define来定义一个关于#pragma的宏是不可行的。

       不过,新的关键字“_Pragma”就很好的解决了问题,由于_Pragma并不能有字符“#”,所以我们可以放心的定义宏:

       #define OPT_L(X) PRAGMA(OPT_LEVEL X)

       #define PRAGMA(X) _Pragma(#X)

       这时,我们只要写:

       OPT_L(2)

       经过预处理后,就成为:

       _Pragma(“OPT_LEVEL 2”)

       即:

       #pragma OPT_LEVEL 2


原文地址:http://blog.163.com/smile_lxj/blog/static/2195626200821445250487/

阅读(1645) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~