在 VS2013 中遇到问题,并询问这怎么可能?
客户在生产中具有以下宏。(具体内容已更改)
#define IS_NONE( charPtr ) ( ( charPtr == "none" || charPtr == "N/A" ) ? TRUE : FALSE )
我的问题是当请求一个名为“none”的块时代码崩溃了。代码应该已经识别出一个“无”块并跳过请求该块。但它没有这样做?
我知道客户代码在 VS6.0 中运行生产,但仅在 VS2013 中崩溃。答案如下。
在 VS2013 中遇到问题,并询问这怎么可能?
客户在生产中具有以下宏。(具体内容已更改)
#define IS_NONE( charPtr ) ( ( charPtr == "none" || charPtr == "N/A" ) ? TRUE : FALSE )
我的问题是当请求一个名为“none”的块时代码崩溃了。代码应该已经识别出一个“无”块并跳过请求该块。但它没有这样做?
我知道客户代码在 VS6.0 中运行生产,但仅在 VS2013 中崩溃。答案如下。
下面的测试用例在 Visual Studio 6.0 中构建。
默认的 Visual Studio6.0 行为是“Program Database with Edit and Continue”。事实证明这启用了字符串池。因此编译器将所有编译时字符串扫描并优化到一个池中,并消除重复的字符串。因此,下面所有“none”和“N/A”的字面定义都将指向相同的物理地址。结果,字符串比较似乎起作用了。
任何动态创建的字符串都将无法匹配,因为它们的地址始终是唯一的。
要让这个测试用例无法在 VS 6.0 中使用“程序数据库”构建它(参见下面的屏幕截图)。
//
// Slight changes to my program from what I compiled
#include "stdio.h"
#define IS_NONE( a_key ) ( ( a_key == "none" || a_key == "N/A" ) ? TRUE : FALSE )
HOST_BEGIN_BLOCK( TestCase ) {
char *psNameNone = "none";
char *psNameNA = "N/A";
char *psNameCAT = "CAT";
if (IS_NONE(psNameNone) ) {
printf("psNameNone Matches NONE\n");
printf("%s psNameNoneAddr 0x%x \"none\" addr 0x%X\n",
psNameNone,psNameNone,
"none");
} else {
printf("psNameNone Does Not Match None\n");
printf("%s psNameNoneAddr 0x%x \"none\" addr 0x%X\n",
psNameNone,psNameNone,
"none");
}
if (IS_NONE(psNameNA) ) {
printf("psNameNA Matches N/A\n");
printf("%s psNameNA 0x%x \"N/A\" addr 0x%X\n",
psNameNA,psNameNA,
"N/A");
} else {
printf("psNameNone Does Not Match N/A\n");
printf("%s psNameNA 0x%x \"N/A\" addr 0x%X\n",
psNameNA,psNameNA,
"N/A");
}
if (IS_NONE(psNameCAT)) {
printf("psNameNA Matches CAT\n");
printf("%s psNameNA 0x%x \"CAT\" addr 0x%X\n",
psNameNone,psNameNone,
"CAT");
} else {
printf("psNameNA does not match CAT\n");
printf("%s psNameNA 0x%x \"CAT\" addr 0x%X\n",
psNameNone,psNameNone,
"CAT");
}
}
下面是测试用例通过的图像。请注意,所有字符串 ADDRESSES 都是相同的。
这是测试用例失败,正如人们期望的不正确的比较语法一样。
希望这将有助于其他人试图弄清楚为什么 VS6.0-> 现代编译器端口似乎可以在 VS6.0(1998 编译器)上工作,但在现代编译器上却失败了。