这是一个简单例子#define DEF_SYMBOL (x){ \
#ifndef (x) \
#define (x) \
#endif \
}报错,编译不能通过
错误 1 error C2065: “x”: 未声明的标识符
错误 2 error C2121: “#”: 无效字符 : 可能是宏展开的结果
这是语法有问题还是预编译指令不允许这样多次迭代解释?

解决方案 »

  1.   

    用意很简单,用一句宏来代替三句宏DEF_SYMBOL(Symbol1)这样理论上可以展开以下三句预编译指令
    #ifndef (Symbol1)
    #define (Symbol1)
    #endif 
    但是预编译器不支持多层迭代解释预编译指令的话就会报错了,这是VC的问题还是ANSI规范C/C++时忽略的问题
      

  2.   

    #define DEF_SYMBOL(x){ \
    #ifndef ##x \
    #define ##x \
    #endif \
    }将宏改了一下,用符号解释操作符来标识x,也是不能通过
      

  3.   

    估计你想问的是在预编译的时候是先进行宏展开还是条件编译,在这里如果先宏展开的话条件编译就成问题了
    例如:
    #define WRONG 1
    #define MAX(x,y,z) { \
    #ifndef WRONG \
    z = (x>y)?x:y; \
    #else \
    z = (x>y)?y:x; \
    #endif \
    }
    编译出错了,报错是 expected macro formal parameter在第二行
    也就是说展开后#ifndef 没办法解释了 
      

  4.   

    是不是换行符在宏展开的时候被去掉了?
    所以不能编译器不能解释 #ifndef
      

  5.   

    #ifdef之类的宏是不是能这么用值得怀疑
    宏内部是不允许夹杂其他预编译指令的
    你应该改为
    #ifndef (x)
    #define DEF_SYMBOL (x)
    #endif 
      

  6.   

    再进一步仔细看,发现可能是C标准定义时有符号定义冲突了在宏体里,#会变成是字符串化操作符,会将符号后面参数变成字符串
    但是预编译指令也是用#作前缀
    这样就带来了问题,#define在宏体里将会被解释成define是个待字符串化的宏参数
    这样说这就是ANSI定标准时留下的缺陷了
      

  7.   

    直接使用:
    #define DEF_SYMBOL (x) \
    #ifndef (x) \
    #define (x) \
    #endif 
    VC6.0下通过.楼主的定义生成的是
    {
         #ifndef (x) \
    #define (x) \
    #endif 
    }
    代码实际上在一个匿名代码块里面,当然无法访问.
      

  8.   

    语法定义不可能按照一种你想象的办法任意组合的。我相信一开始就没有想过要在宏定义中使用#if/#ifndef之类的预编译指令。
      

  9.   

    私以为,作为一个合格的宏功能,是不应该有语法限制的,只需要提供代码展开这个功能就够了,预编译指令更不应该被限制
    相比之下,MASM提供的宏功能就好多了,可以在宏体里支持99%的指令(当然还有个LOCAL指令是冲突的)