Неопределенное поведение при добавлении const с const_cast? - PullRequest
1 голос
/ 08 февраля 2012

Этот вопрос касается поведения, которое я наблюдал при использовании const_cast для создания char * const char *.Мне известно, что это приведение выполняется неявно, и t работает для меня, когда приведение выполняется неявно.

Проблемный код:

#include <cstdlib>
int main() {
    const char * org_str = NULL;
    org_str = const_cast<const char*>(getenv("ENV_VAR")); // PROBLEM !!
}

Согласно Справочная страница Linux getenv() принимает const char * и возвращает char*.Итак, в соответствии с моим пониманием правильности констант, я могу без проблем выполнить приведение констант на char*.

Итак, мой вопрос: почему const_cast здесь дает мне UB (код падает) но, как и ожидалось, без const_cast (неявное приведение) работает нормально (так что проблема должна быть с использованием const_cast)?

Обратите внимание, я знаю, что неявное приведение - это путь сюдаВ этом посте мне нужен ответ специально для поведения, наблюдаемого здесь.

РЕДАКТИРОВАТЬ:

Поскольку ошибка не воспроизводится другими соратниками, я предполагаю, что это странная среда выполнения /проблема с компилятором.Но, дайте мне знать, есть ли упоминание о таких проблемах в стандарте.

Пока я принимаю ответ Майка.

Ответы [ 3 ]

3 голосов
/ 08 февраля 2012

Вы приводите указатель на функцию, а не указатель, возвращаемый функцией.Сначала вызовите функцию с помощью (), , затем приведите результат.

РЕДАКТИРОВАТЬ: Я не могу воспроизвести проблему.Вот код, который я использовал:

#include <cstdlib>
#include <iostream>

using namespace std;
int main() {
    const char * org_str = NULL;
    org_str = const_cast<const char*>(getenv("PATH"));
    cout << "Got: " << org_str << endl;
}

Вот что я получил:

$ g++ foo.cc -o foo.app
$ ./foo.app
Got: /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/X11R6/bin
$

Кстати, назначение NULL не нужно;Рекомендуемая практика заключается в использовании одного из:

const char *org_str = const_cast<const char*>(getenv("PATH"));

const char *org_str(const_cast<const char*>(getenv("PATH")));

const char *org_str(getenv("PATH"));
2 голосов
/ 08 февраля 2012

Вам не нужно const_cast<>, чтобы сделать что-то постоянным, вам нужно только его, чтобы убрать постоянство.

Кроме того, я не верю, что код, который у вас есть, является правильным, поскольку getenv - это функция, и похоже, что вы используете ее как переменную. Возможно, что-то вроде этого будет работать:

const char * org_str = getenv("name-of-env");
0 голосов
/ 08 февраля 2012

Насколько я понимаю, это не возвращаемое значение getenv, которое вы должны разыграть, а const char, который у вас есть. Поскольку org_str является константой, вы не можете назначить ее без использования const_cast, что означает, что вам нужно будет сделать что-то вроде:

#include <cstdlib>
int main() {
    const char * org_str = NULL;
    const_cast<char*>(org_str) = getenv("ENV_VAR"); // NO PROBLEM !!
}

РЕДАКТИРОВАТЬ: Что касается const_cast для getenv, это не имеет смысла, так как вы не назначаете это, и поэтому не будет никаких нарушений выражения const, как

org_str = getenv("ENV_VAR") will give you.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...