Когда может работать плохое сравнение строк?String Pooling VS6.0 - PullRequest
0 голосов
/ 21 января 2019

В VS2013 столкнулся с проблемой и спрашивал, КАК ЭТО БЫЛО СДЕЛАНО?
У заказчика был следующий макрос в производстве. (особенности были изменены)

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

Моя проблема заключалась в сбое кода при запросе блока с именем none. Код должен был идентифицировать блок «none» и пропустить запрос на блок. Но это не удалось сделать?
Я знал, что код клиента работал в VS6.0, но только в VS2013. Ответ ниже.

1 Ответ

0 голосов
/ 21 января 2019

Тестовый пример, приведенный ниже, построен в Visual Studio 6.0.

Поведение Visual Studio6.0 по умолчанию - «База данных программы с редактированием и продолжением». Оказывается, это позволяет STRING POOLING. Таким образом, компилятор просматривает и оптимизирует ВСЕ строки времени компиляции в пул, а дублирующиеся строки удаляются. Таким образом, все буквальные определения «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

Ниже приведено изображение прохождения тестового примера. Обратите внимание, что все строки АДРЕСА одинаковы.

Построен с «Программная база данных с редактированием и продолжением» Passing Test Case--Should fail

Этот тестовый пример не пройден, как и следовало ожидать, если использовать неправильный синтаксис сравнения.

Построен с помощью «Базы данных программ». Failing Test Case--Expected Behavior

Надеюсь, это поможет другим попытаться выяснить, почему порты компилятора VS6.0-> Modern работают на VS6.0 (компилятор 1998 года), но не работают с современным компилятором.

...