Вопрос

§5.3.1 Унарные операторы, раздел 3

Результатом унарного оператора & является указатель на его операнд. Операнд должен быть lvalue или квалифицированный идентификатор.

Что именно означает «должно быть» в данном контексте?Означает ли это, что брать адрес временный - ошибка?Мне просто интересно, потому что g++ только выдает мне предупреждение, тогда как Comeau отказывается компилировать следующую программу:

#include <string>

int main()
{
    &std::string("test");
}

г++ предупреждение: taking address of temporary

комо ошибка: expression must be an lvalue or a function designator

Есть ли у кого-нибудь компилятор Microsoft или другие компиляторы, и он может протестировать эту программу, пожалуйста?

Это было полезно?

Решение

Слово «должен» на стандартном языке означает строгое требование.Итак, да, ваш код неправильно сформирован (это ошибка), поскольку он пытается применить оператор адреса к значению, отличному от lvalue.

Однако проблема здесь не в попытке взять адрес временный.Проблема, опять же, в том, чтобы взять адрес не-значение.Временный объект может быть lvalue или не lvalue в зависимости от выражения, которое создает этот временный объект или обеспечивает доступ к этому временному объекту.В вашем случае у вас есть std::string("test") - функциональный стиль, приведенный к нессылочному типу, который по определению создает не-lvalue.Отсюда и ошибка.

Если вы хотите получить адрес временного объекта, вы могли бы обойти это ограничение, например, следующим образом:

const std::string &r = std::string("test");
&r; // this expression produces address of a temporary

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

Другие советы

Когда в стандарте C++ используется слово «должен», оно означает «должен под страхом смерти» — если реализация не подчиняется этому, она неисправна.

Это разрешено в MSVC с устаревшей опцией /Ze (расширения включены).Это было разрешено в предыдущих версиях MSVC.Он генерирует диагностику со всеми включенными предупреждениями:

предупреждение C4238:используется нестандартное расширение:класс rvalue, используемый как lvalue.

Если не используется параметр /Za (обеспечивает совместимость ANSI), то:

ошибка C2102:'&' требует l-значения

&std::string("test"); запрашивает адрес возвращаемого значения вызова функции (мы проигнорируем как несущественный тот факт, что эта функция является ctor).У него не было адреса, пока вы не присвоили его чему-то.Следовательно, это ошибка.

Стандарт C++ фактически является требованием для соответствующих реализаций C++.Местами написано, чтобы различать код, который должны принимать соответствующие реализации, и код, для которого соответствующие реализации должны выдавать диагностику.

Итак, в данном конкретном случае совместимый компилятор должен дать диагностику, если взят адрес rvalue.Оба компилятора это делают, поэтому в этом отношении они согласуются.

Стандарт не запрещает создание исполняемого файла, если определенный ввод вызывает диагностику, т.е.предупреждения являются действительной диагностикой.

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

определяемое пользователем преобразование

struct String {
    std::string str;

    operator std::string*() {
        return &str;
    }
};

std::string *my_str = String{"abc"};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top