大家来看,这是VC预编译处理的粗糙落后还是代码写得不对

xgen007 2010-07-03 01:14:48
这是一个简单例子

#define DEF_SYMBOL (x){ \
#ifndef (x) \
#define (x) \
#endif \
}

报错,编译不能通过
错误 1 error C2065: “x”: 未声明的标识符
错误 2 error C2121: “#”: 无效字符 : 可能是宏展开的结果


这是语法有问题还是预编译指令不允许这样多次迭代解释?
...全文
110 点赞 收藏 17
写回复
17 条回复
arong1234 2010年07月03日
是不是合格就要看宏定义的语法规定了,这个咱从来不擅长。我比较喜欢用最简单的代码实现我要的功能,所以对这种东西一向钻研很少[Quote=引用 15 楼 xgen007 的回复:]
引用 11 楼 arong1234 的回复:

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



私以为,作为一个合格的宏功能,是不应该有语法限制的,只需要提供代码展开这个功能就够了,预编译指令更不应该被限制
相比之下,MASM提供的宏功能就好……
[/Quote]
回复 点赞
xgen007 2010年07月03日
[Quote=引用 13 楼 lisunlin0 的回复:]

直接使用:
#define DEF_SYMBOL (x) \
#ifndef (x) \
#define (x) \
#endif
VC6.0下通过.

楼主的定义生成的是
{
#ifndef (x) \
#define (x) \
#endif
}
代码实际上在一个匿名代码块里面,当然无法访问.
[/Quote]

把括号去掉我早就试过了,也是报错的,不知道你是怎么实现的了
回复 点赞
xgen007 2010年07月03日
[Quote=引用 11 楼 arong1234 的回复:]

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


私以为,作为一个合格的宏功能,是不应该有语法限制的,只需要提供代码展开这个功能就够了,预编译指令更不应该被限制
相比之下,MASM提供的宏功能就好多了,可以在宏体里支持99%的指令(当然还有个LOCAL指令是冲突的)
回复 点赞
arong1234 2010年07月03日
语法定义不可能按照一种你想象的办法任意组合的。我相信一开始就没有想过要在宏定义中使用#if/#ifndef之类的预编译指令。[Quote=引用 12 楼 xgen007 的回复:]
再进一步仔细看,发现可能是C标准定义时有符号定义冲突了

在宏体里,#会变成是字符串化操作符,会将符号后面参数变成字符串
但是预编译指令也是用#作前缀
这样就带来了问题,#define在宏体里将会被解释成define是个待字符串化的宏参数
这样说这就是ANSI定标准时留下的缺陷了
[/Quote]
回复 点赞
lisunlin0 2010年07月03日
直接使用:
#define DEF_SYMBOL (x) \
#ifndef (x) \
#define (x) \
#endif
VC6.0下通过.

楼主的定义生成的是
{
#ifndef (x) \
#define (x) \
#endif
}
代码实际上在一个匿名代码块里面,当然无法访问.
回复 点赞
xgen007 2010年07月03日
再进一步仔细看,发现可能是C标准定义时有符号定义冲突了

在宏体里,#会变成是字符串化操作符,会将符号后面参数变成字符串
但是预编译指令也是用#作前缀
这样就带来了问题,#define在宏体里将会被解释成define是个待字符串化的宏参数
这样说这就是ANSI定标准时留下的缺陷了
回复 点赞
arong1234 2010年07月03日
#ifdef之类的宏是不是能这么用值得怀疑
宏内部是不允许夹杂其他预编译指令的
你应该改为
#ifndef (x)
#define DEF_SYMBOL (x)
#endif

回复 点赞
waixinget2009 2010年07月03日
其实你这里三行和一行的定义效果是一样的吧
回复 点赞
waixinget2009 2010年07月03日
是不是换行符在宏展开的时候被去掉了?
所以不能编译器不能解释 #ifndef
回复 点赞
waixinget2009 2010年07月03日
估计你想问的是在预编译的时候是先进行宏展开还是条件编译,在这里如果先宏展开的话条件编译就成问题了
例如:
#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 没办法解释了
回复 点赞
xgen007 2010年07月03日
#define DEF_SYMBOL(x){ \
#ifndef ##x \
#define ##x \
#endif \
}

将宏改了一下,用符号解释操作符来标识x,也是不能通过
回复 点赞
xgen007 2010年07月03日
用意很简单,用一句宏来代替三句宏

DEF_SYMBOL(Symbol1)

这样理论上可以展开以下三句预编译指令
#ifndef (Symbol1)
#define (Symbol1)
#endif
但是预编译器不支持多层迭代解释预编译指令的话就会报错了,这是VC的问题还是ANSI规范C/C++时忽略的问题
回复 点赞
waixinget2009 2010年07月03日
你这里像是用的一个语句作为宏的展开,{...}
具体用法能不能给点提示
回复 点赞
xgen007 2010年07月03日
。。。。。。
回复 点赞
向立天 2010年07月03日
[Quote=引用 2 楼 xgen007 的回复:]
LS有引用到宏么
[/Quote]没有
回复 点赞
xgen007 2010年07月03日
LS有引用到宏么
回复 点赞
向立天 2010年07月03日
VS2005
编译通过
回复 点赞
发动态
发帖子
VC/MFC
创建于2007-09-28

7898

社区成员

42.1w+

社区内容

VC/MFC相关问题讨论
社区公告
暂无公告