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

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

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

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


这是语法有问题还是预编译指令不允许这样多次迭代解释?
...全文
152 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
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]
sunlin7 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
编译通过

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧