VS 2008 中 C++/MFC 编译器的奇怪结果

Posted

技术标签:

【中文标题】VS 2008 中 C++/MFC 编译器的奇怪结果【英文标题】:Strange result from a C++/MFC compiler in VS 2008 【发布时间】:2013-11-24 03:53:15 【问题描述】:

我以为我非常了解 VS 2008 C++ 编译器:

CString str;
str.Empty();
LPCTSTR pStr = str.IsEmpty() ? NULL : str;
::MessageBox(NULL, pStr ? L"pStr is NOT null" : L"pStr is null", L"Result", MB_OK);

谁能解释我为什么会得到这个?

【问题讨论】:

与 VS2012 相同。似乎是影响它的三元运算符 - 替换为if/else,一切都很好。看起来三元运算符创建了一个带有 NULL 内容的 LPCTSTR,而不是将 NULL 分配给 LPCTSTR。我不知道为什么,所以 +1 来回答一个可能会遇到问题的好问题。 在 VS2010 中也会发生同样的事情; LPCTSTR pStr = str.IsEmpty() ? NULL : str.GetBuffer(); 确实返回 NULL——很奇怪,我也希望有人能解释一下! 另一种解决方法是str.GetString(); @Edward GetBuffer() 返回一个指向 modifiable 缓冲区 (LPTSTR) 的指针。它仅在您需要手动更改受控字符数组时使用。完成后您必须致电ReleaseBuffer()。如果您需要指向非可变缓冲区 (LPCTSTR) 的指针,请改为调用 GetString() 【参考方案1】:

LPCTSTR pStr = str.IsEmpty() ? (LPCTSTR)NULL : str; 确实返回 NULL

看起来发生这种情况是因为这两个表达式的类型不同; MSDN Docs 说

如果两个表达式都是指针类型,或者一个是指针类型 另一个是计算结果为 0 的常量表达式,指针 执行转换以将它们转换为通用类型

引用a MSDN forum post:

5.16-3- 在标准中描述了这里发生的类型强制;表达式 (B ? E1 : E2) 只能有一个类型,所以如果 表达式 E1 和 E2 的类型不同,它们必须被强制 在评估任一表达式之前转换为通用的安全类型 发生...所以,本例中 E1 的类型是 CString,而 E2 的类型是 int。 5.16-3中描述的过程-最终 得出的结论是,这两种转换为的唯一安全类型是 字符串。

【讨论】:

好找到了! +1 持久性 - 我知道你引用了 MSDN,但我看到它背后有一个 C/C++ 标准,所以它必须与其他编译器相似。 感谢您的分析。在这种情况下,至少会有一个编译器警告。

以上是关于VS 2008 中 C++/MFC 编译器的奇怪结果的主要内容,如果未能解决你的问题,请参考以下文章

使用 Visual Studio 2008 编译和运行 MFC 应用程序?

vs2008 MFC问题编译无法通过

用 VS2008 重新编译代码,现在它重新启动 XP SP2

C# VS2008 编译器选择错误的方法

用vs2008做的MFC程序,怎么在WINDOWS XP下运行?

如何从VS2008代码分析中排除MFC代码