предупреждение: устарело преобразование из строковой константы в ‘ACE_TCHAR*’

Я пытаюсь написать модульные тесты, в которых мы вызываем конструктор универсального класса в форме:

void testConstructor() {
    int argc = 2;
    ACE_TCHAR* argv[] = {"Input1", "Input2"};
    MyClass *myClass = new MyClass(argc, argv);
    /**processing**/
}

Думайте о ACE_TCHAR* так же, как char*. Приведенный выше код приводит к

warning: deprecated conversion from string constant to ‘ACE_TCHAR*’

Я также пробовал:

void testConstructor() {
    int argc = 2;
    ACE_TCHAR* argv[2];
    argv[0] = "Input1";
    argv[1] = "Input2";
    MyClass *myClass = new MyClass(argc, argv);
    /**processing**/
}

Что приводит к той же ошибке.

Я где-то читал в Интернете, что это можно смягчить, используя

const ACE_TCHAR* argv[] = {"Input1", "Input2"};

Но тогда компиляция завершается ошибкой из-за сигнатуры функции.

Изменить: мне не разрешено изменять сторонний код, я пишу для него только модульные тесты.

Любые идеи?


person Tyler Jandreau    schedule 01.02.2013    source источник
comment
Очевидное исправление — заставить конструктор принимать const указателей.   -  person molbdnilo    schedule 01.02.2013
comment
Не используйте class в качестве идентификатора. Это зарезервированное ключевое слово в C++. Используйте, возможно, klass   -  person Basile Starynkevitch    schedule 01.02.2013
comment
Нам не разрешено изменять src, предоставленный третьей стороной. Эта мысль пришла мне в голову.   -  person Tyler Jandreau    schedule 01.02.2013


Ответы (2)


Строковая константа, как следует из названия, является константой. Таким образом, чтобы предупреждение исчезло, правильным решением действительно было бы превратить указатель в постоянный указатель.

Если это невозможно сделать, вы можете явно приводить типы

ACE_TCHAR* argv[] = {const_cast<ACE_TCHAR*>("Input1"),
                     const_cast<ACE_TCHAR*>("Input2")};

или сначала назначьте строки непостоянным массивам символов

char input1[] = "Input1";
char input2[] = "Input2";
ACE_TCHAR* argv[] = {input1, input2};
person Mr Lister    schedule 01.02.2013
comment
Превосходно! Спасибо, сэр, именно то, что я искал. - person Tyler Jandreau; 01.02.2013

Тип строкового литерала — «массив const char». Благодаря неявному преобразованию массива в указатель вы можете использовать это для инициализации или присвоения const char *.

Но есть специальное правило, согласно которому строковый литерал также может быть неявно преобразован в char * (без константы). Это правило существует для совместимости со старым кодом C, где char * str = "string literal" было распространенной идиомой. Использование этого опасно, потому что изменение указанного массива символов с помощью этого указателя приводит к неопределенному поведению (т. е. ваша программа может рухнуть или может произойти что-то еще). По этой причине конструкция устарела, и ваш компилятор предупреждает вас об этом.

Чтобы создать действительные данные, которые вы можете передать как неконстантные указатели на символы, вы можете использовать

const int argc = 2;
ACE_TCHAR argv0[] = "Input1";
ACE_TCHAR argv1[] = "Input2";
ACE_TCHAR* argv[] = { argv0, argv1 };
MyClass *myClass = new MyClass(argc, argv);
person JoergB    schedule 01.02.2013