undef这个宏的问题

liuzu2016 2013-04-02 11:09:46
例子1:

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE // 这个宏就被取消成功了? 如果成功的话,提供个第2个例子,为什么第二个例子不成功?
static char THIS_FILE[] = __FILE__;
#endif



例子2:

int main ()
{

#ifdef _UNICODE
#undef _UNICODE //我已经取消掉了,那么TCHAR则是char!!!


TCHAR strDirectory[]=_T("c:\\1111\\222\\");

if (!PathFileExists(strDirectory))
{

char strTemp[MAX_PATH]={0};

// _tcsncpy(strTemp,strDirectory,lstrlen(strDirectory));

//PathRemoveBackslash(strDirectory);

//PathAddBackslash(strDirectory);

MakeSureDirectoryPathExists(strDirectory); //error,取消掉宏了,为什么还出错?

}
#endif


return 0;

}

有人说例子2失败的原因:

是顺序问题,

对于取消一个宏, 编译器只看第一次定义的时候,

不会看中途的代码的。




...全文
382 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-10-16
  • 打赏
  • 举报
回复
编译选项加/EP /P,重新编译,查看宏展开后对应的.i文件。gcc加-E
xing_ping_1987 2014-10-16
  • 打赏
  • 举报
回复
MakeSureDirectoryPathExists 不支持unicode 使用SHCreateDirectoryEx
bsnry 2013-04-07
  • 打赏
  • 举报
回复
引用 14 楼 liuzu2016 的回复:
引用 13 楼 ri_aje 的回复:引用 6 楼 liuzu2016 的回复:这个解释可能不对,。你得参考函数;MakeSureDirectoryPathExists BOOL MakeSureDirectoryPathExists( PCSTR Dirpath ); 这个不持unicode的,msdn已经说了. 有年头没在 windows 下混了,有时候……
liuzu2016 2013-04-03
  • 打赏
  • 举报
回复
引用 13 楼 ri_aje 的回复:
引用 6 楼 liuzu2016 的回复:这个解释可能不对,。你得参考函数;MakeSureDirectoryPathExists BOOL MakeSureDirectoryPathExists( PCSTR Dirpath ); 这个不持unicode的,msdn已经说了. 有年头没在 windows 下混了,有时候知识有些陈旧,见谅。 引用 6 ……
不好意思,不知道你们没有搞windows。 可以加上这2条指令: #pragma comment(lib,"Shlwapi.lib") #pragma comment(lib,"Dbghelp.lib") 可以让你链接过去 我总结了一下你们的答案: 先说例子2: 应该在tchar.h之前 #undef掉 _unicode这个宏,才能够影响到 TCHAR的类型(TCHAR不是宏 是一个类型, 这里是无法通过取消_unicode来影响它,改变他,要改变,也必须在 #include<tchar.h>之前。 例子1的解释:
引用 11 楼 lin5161678 的回复:
引用 10 楼 liuzu2016 的回复:#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE // 这个宏就被取消成功了? 如果成功的话,提供个第2个例子,为什么第二个例子不成功? static char THIS_FILE[] = __FILE__; #endif 你自己看看 这里的做法是 取……
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE // 这个宏就被取消成功了? 如果成功的话,提供个第2个例子,为什么第二个例子不成功? static char THIS_FILE[] = __FILE__; #endif THIS_FILE 这个宏, 特意建立一个工程(用vc6建立 的) 出现: #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif 这么几句代码,那么#undef在这里到底有没有取消成功呢? 把其注释掉就知道了。 去掉后,很明显, 编译出错了。 说明取消是成功的。 THIS_FILE是一个宏,而非 一个像TCHAR的类型,所以可以取消成功. #undef这个宏,是管用的, 只是我把两个问题混在一块了
ri_aje 2013-04-02
  • 打赏
  • 举报
回复
引用 1 楼 ri_aje 的回复:
把第二个例子完整可编译的例子发上来,怀疑是 undef 不够靠前导致的。
忘记说了,特别是 #include 要发全了。
ri_aje 2013-04-02
  • 打赏
  • 举报
回复
把第二个例子完整可编译的例子发上来,怀疑是 undef 不够靠前导致的。
ri_aje 2013-04-02
  • 打赏
  • 举报
回复
引用 6 楼 liuzu2016 的回复:
这个解释可能不对,。你得参考函数;MakeSureDirectoryPathExists

BOOL MakeSureDirectoryPathExists(
PCSTR Dirpath
);
这个不持unicode的,msdn已经说了.

有年头没在 windows 下混了,有时候知识有些陈旧,见谅。

引用 6 楼 liuzu2016 的回复:
我的理解诶是: main里的_undef取消不成功导致的……

_undef 是啥?我不知道你是打字错误,还是故意在说另一个东西。无论如何 #undef 的行为有标准定义,一定会成功的。

下面是我自己写的一个例子,在 win7 vs2010 下编译成功,但出现链接错误,原因是找不到 PathFileExists 和 MakeSureDirectoryPathExists 的定义,后者已经出离本贴的问题,所以我没有深究。

#ifdef _UNICODE
#undef _UNICODE
// #undef clearly directed TCHAR to be defined as char
// even if I made my projected character set unicode
// as verified by the following screenshot.
#include <tchar.h>
#endif

#ifdef UNICODE
#undef UNICODE
// PathFileExists can be PathFileExistsW or PathFileExistsA and
// my Shlwapi.h shows that its declaration is controlled by the
// predefined macro UNICODE, not _UNICODE.
// not sure what's the difference between them.
#include <Shlwapi.h> // PathFileExists
#endif

// as you said earlier, there is only one MakeSureDirectoryPathExists
#include <DbgHelp.h> // MakeSureDirectoryPathExists

// if your compiler does not support this file or the later static_assert,
// then take them out.
#include <type_traits> // std::is_same

int main ()
{
TCHAR strDirectory [] = _T("c:\\1111\\222\\");
static_assert(std::is_same<TCHAR,char>::value,"bad");
if (!PathFileExists(strDirectory))
{
MakeSureDirectoryPathExists(strDirectory);
}
return 0;
}

lin5161678 2013-04-02
  • 打赏
  • 举报
回复
引用 10 楼 liuzu2016 的回复:
引用 9 楼 lin5161678 的回复:楼主的做法 C/C++ code?123456#define _UNICODE#ifdef _UNICODEtypedef WCHAR TCHAR;#endif #undef _UNICODE 完成预编译之后的代码是 C/C++ code?1typedef WCHAR TCHAR; 楼主期望的做法应该是 C/C++……
稍微思考一下 关于预编译的过程
lin5161678 2013-04-02
  • 打赏
  • 举报
回复
引用 10 楼 liuzu2016 的回复:
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE // 这个宏就被取消成功了? 如果成功的话,提供个第2个例子,为什么第二个例子不成功? static char THIS_FILE[] = __FILE__; #endif
你自己看看 这里的做法是 取消THIS_FILE 然后定义THIS_FILE 是同一个 你的做法是企图 取消_UNICODE 导致取消 TCHAR 不是同一个
liuzu2016 2013-04-02
  • 打赏
  • 举报
回复
引用 9 楼 lin5161678 的回复:
楼主的做法 C/C++ code?123456#define _UNICODE#ifdef _UNICODEtypedef WCHAR TCHAR;#endif #undef _UNICODE 完成预编译之后的代码是 C/C++ code?1typedef WCHAR TCHAR; 楼主期望的做法应该是 C/C++ code?1234567#define _……
好吧, 假设你的第2个例子解释合理,因为tchar 是wchar_t,那么 请解释第一个例子: #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE // 这个宏就被取消成功了? 如果成功的话,提供个第2个例子,为什么第二个例子不成功? static char THIS_FILE[] = __FILE__; #endif 第2个例子,取消不了。 为什么第一个就取消成功了? 我为什么说第2个取消不了呢? 看源码: MakeSureDirectoryPathExists的参数必须是char* 这个函数只有一个版本呢,不存在unicode 你可以看msdn的要求。 你们都混淆了一个观念,以为这个函数有2个版本呢,其实非也.
lin5161678 2013-04-02
  • 打赏
  • 举报
回复
楼主的做法


#define _UNICODE
#ifdef _UNICODE
typedef WCHAR TCHAR;
#endif

#undef _UNICODE
完成预编译之后的代码是
typedef WCHAR TCHAR;
楼主期望的做法应该是
#define _UNICODE

#undef _UNICODE // 你的这句代码应该在这个位置 才有你想要的作用

#ifdef _UNICODE
typedef WCHAR TCHAR;
#endif
预编译完成之后是
没错就是什么都没有了 楼主好好体会一下
lin5161678 2013-04-02
  • 打赏
  • 举报
回复
引用 6 楼 liuzu2016 的回复:
引用 5 楼 ri_aje 的回复:试试把这两句放在所有 include 之前,即文件最开始。 C/C++ code?12#ifdef _UNICODE#undef _UNICODE //我已经取消掉了,那么TCHAR则是char!!! 我理解原因是 preprocessor 进来以后按顺序处理,到达 #include <windows.h> 的时候 _UNI……
取消是取消成功的 这点毋庸置疑
lin5161678 2013-04-02
  • 打赏
  • 举报
回复
楼主 你是 #define _UNICODE #ifdef _UNICODE 定义wchar ......... #undef _UNICODE 你的#undef 太晚了 定义wchar的代码已经在源文件里面的 你想#undef 使wchar不生效 应该是在 定义wchar之前 就是这样 #define _UNICODE #undef _UNICODE // 你的这句代码应该在这个位置 才有你想要的作用 #ifdef _UNICODE 定义wchar .........
liuzu2016 2013-04-02
  • 打赏
  • 举报
回复
引用 5 楼 ri_aje 的回复:
试试把这两句放在所有 include 之前,即文件最开始。 C/C++ code?12#ifdef _UNICODE#undef _UNICODE //我已经取消掉了,那么TCHAR则是char!!! 我理解原因是 preprocessor 进来以后按顺序处理,到达 #include <windows.h> 的时候 _UNICODE 还是有定义的,因此生成的函……
这个解释可能不对,。你得参考函数;MakeSureDirectoryPathExists BOOL MakeSureDirectoryPathExists( PCSTR Dirpath ); 这个不持unicode的,msdn已经说了. 我的理解诶是: main里的_undef取消不成功导致的
ri_aje 2013-04-02
  • 打赏
  • 举报
回复
试试把这两句放在所有 include 之前,即文件最开始。

#ifdef  _UNICODE
#undef  _UNICODE //我已经取消掉了,那么TCHAR则是char!!!
我理解原因是 preprocessor 进来以后按顺序处理,到达 #include <windows.h> 的时候 _UNICODE 还是有定义的,因此生成的函数对应 unicode 的接口,进入 main 以后 _UNICODE 被强行取消,导致生成的字符串类型和函数类型不匹配。
mzz_810 2013-04-02
  • 打赏
  • 举报
回复
在_UNICODE定义取消前,TCHAR已被定义为wchar. 楼主应该直接对TCHAR做重定义。
liuzu2016 2013-04-02
  • 打赏
  • 举报
回复
引用 2 楼 ri_aje 的回复:
引用 1 楼 ri_aje 的回复:把第二个例子完整可编译的例子发上来,怀疑是 undef 不够靠前导致的。 忘记说了,特别是 #include 要发全了。
#include "stdafx.h" #include <stdio.h> #include <windows.h> #include <Shlwapi.h> #include <ShlObj.h> #include <DbgHelp.h> int main() { #ifdef _UNICODE #undef _UNICODE //我已经取消掉了,那么TCHAR则是char!!! TCHAR strDirectory[]=_T("c:\\1111\\222\\"); if (!PathFileExists(strDirectory)) { char strTemp[MAX_PATH]={0}; // _tcsncpy(strTemp,strDirectory,lstrlen(strDirectory)); //PathRemoveBackslash(strDirectory); //PathAddBackslash(strDirectory); MakeSureDirectoryPathExists(strDirectory); //error,取消掉宏了,为什么还出错? } #endif return 0; return 0; } 错误提示:错误 1 error C2664: “MakeSureDirectoryPathExists”: 不能将参数 1 从“TCHAR [13]”转换为“PCSTR” e:\c_plus_plus\最新的demo\test77\test77.cpp 32 test77 stdafx.h里的内容: #pragma once #include "targetver.h" #include <stdio.h> #include <tchar.h> // TODO: 在此处引用程序需要的其他头文件

64,266

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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