C++中的预处理(下)

类别:VC语言 点击:0 评论:0 推荐:

其他预编译指令
    除了上面我们说的集中常用的编译指令,还有3种不太常见的编译指令:#line、#error、#pragma,我们接下来就简单的谈一下。
    #line的语法如下:
      #line number filename
    例如:#line 30  a.h     其中,文件名a.h可以省略不写。
    这条指令可以改变当前的行号和文件名,例如上面的这条预处理指令就可以改变当前的行号为30,文件名是a.h。初看起来似乎没有什么用,不过,他还是有点用的,那就是用在编译器的编写中,我们知道编译器对C++源码编译过程中会产生一些中间文件,通过这条指令,可以保证文件名是固定的,不会被这些中间文件代替,有利于进行分析。
    #error语法如下:
        #error  info
    例如:#ifndef UNIX
             #error This software requires the UNIX OS.
           #endif
    这条指令主要是给出错误信息,上面的这个例子就是,如果没有在UNIX环境下,就会输出This software requires the UNIX OS.然后诱发编译器终止。所以总的来说,这条指令的目的就是在程序崩溃之前能够给出一定的信息。
    至于#pragma,我们在《解析#pragma指令 》一文中有过介绍,我们在这里再补充几句,#pragma是非统一的,他要依靠各个编译器生产者,例如,在SUN C++编译器中:
         // 把name和val的起始地址调整为8个字节的倍数
         #progma align 8 (name, val)
         char   name[9];
         double val;

        file://在程序执行开始,调用函数MyFunction
        #progma init (MyFunction)

预定义标识符
    为了处理一些有用的信息,预处理定义了一些预处理标识符,虽然各种编译器的预处理标识符不尽相同,但是他们都会处理下面的4种:
    __FILE__  正在编译的文件的名字
    __LINE__  正在编译的文件的行号
    __DATE__  编译时刻的日期字符串,例如: "25 Dec 2000"
    __TIME__  编译时刻的时间字符串,例如: "12:30:55"
    例如:cout<<"The file is :"<<__FILE__"<<"! The lines is:"<<__LINE__<<endl;

预处理何去何从
    在《浅析C++里面的宏》一文中,我们提到了如何取代#include预处理指令,我们在这里就不再一一讨论了。
    C++并没有为#include提供替代形式,但是namespace提供了一种作用域机制,它能以某种方式支持组合,利用它可以改善#include的行为方式,但是我们还是无法取代#include。
    #progma应该算是一个可有可无的预处理指令,按照C++之父Bjarne的话说,就是:“#progma被过分的经常的用于将语言语义的变形隐藏到编译系统里,或者被用于提供带有特殊语义和笨拙语法的语言扩充。”
    对于#ifdef,我们仍然束手无策,就算是我们利用if语句和常量表达式,仍然不足以替代她,因为一个if语句的正文必须在语法上正确,满足类检查,即使他处在一个绝不会被执行的分支里面。
    最后,我们以Bjarne博士的话作为结尾:“最后---在许多年之后---将Cpp放逐刀程序开发环境里,与其它附加性语言工具放到一起,那里才是她应该呆的地方。”

本文地址:http://com.8s8s.com/it/it1606.htm