先思考一个问题:
#include <string>
#include <Windows.h>
namespace ui {
int MessageBox(HWND hwnd, const std::wstring &text, const std::wstring &caption,
UINT flags) {
UINT actual_flags = flags;
const wchar_t *text_ptr = text.c_str();
const wchar_t *caption_ptr = caption.c_str();
return ::MessageBox(hwnd, text_ptr, caption_ptr, actual_flags);
}
} // namespace ui
int test_ui_message_box() {
ui::MessageBox(0, L"33333", L"", MB_OK);
ui::MessageBoxW(0, L"33333", L"", MB_OK);
ui::MessageBoxA(0, L"33333", L"", MB_OK);
ui::MessageBoxB(0, L"33333", L"", MB_OK);
return 0;
}
上面test_ui_message_box函数中调用的4个函数能编译通过吗?
答案:
ui::MessageBox(0, L"33333", L"", MB_OK); // 编译成功
ui::MessageBoxW(0, L"33333", L"", MB_OK);// 定义了UNICODE宏时可以编译成功
ui::MessageBoxA(0, L"33333", L"", MB_OK);// 没有定义UNICODE宏时可以编译成功
ui::MessageBoxB(0, L"33333", L"", MB_OK);// 编译失败
为什么会问这个问题?
因为最近在chromium项目中笔误写了一个代码,把系统MessageBox调整为ui命名空间的MessageBox,代码修改如下:
::MessageBoxW ===> ui::MessageBoxW
chromium源码如下:
但是通过上面的定义可以看到,ui命名空间里没有MessageBoxW函数,所以上面我是写了一个笔误,但是竟然编译通过了
所以,引起了我的兴趣:
一个小工具来辅助排查:
VC中如何查看预编译的结果 .i文件:VC中如何查看预编译的结果 .i文件_预处理文件.i怎么看_程序猿-小斑的博客-CSDN博客
即编译cpp文件时使用/P命令行,可以看到预处理之后的真实文件内容。
上面代码的编译结果:(定义了UNICODE宏)
在定义了UNICODE宏之后,ui命名空间的真实函数名称就是 MessageBoxW,而且调用ui::MessageBox 函数的地方也被替换成了 ui::MessageBoxW。
这两个地方的名称是被系统全局的宏定义替换之后的结果:
google code style中对使用宏的建议:
Google C++ Style Guide