0

在 VS2013 中遇到问题,并询问这怎么可能?
客户在生产中具有以下宏。(具体内容已更改)

#define IS_NONE( charPtr )  ( ( charPtr == "none" || charPtr == "N/A" ) ? TRUE : FALSE )

我的问题是当请求一个名为“none”的块时代码崩溃了。代码应该已经识别出一个“无”块并跳过请求该块。但它没有这样做?
我知道客户代码在 VS6.0 中运行生产,但仅在 VS2013 中崩溃。答案如下。

4

1 回答 1

0

下面的测试用例在 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");
    }
}

ProgramDatabaseShot

下面是测试用例通过的图像。请注意,所有字符串 ADDRESSES 都是相同的。

使用“带有编辑和继续的程序数据库”构建 通过测试用例——应该失败

这是测试用例失败,正如人们期望的不正确的比较语法一样。

内置“程序数据库” 失败的测试用例——预期的行为

希望这将有助于其他人试图弄清楚为什么 VS6.0-> 现代编译器端口似乎可以在 VS6.0(1998 编译器)上工作,但在现代编译器上却失败了。

于 2019-01-21T18:40:05.263 回答