Почему строковый литерал в С++ это l-value?

296
25 июля 2017, 19:01

Например строковый литерал: "Hello, world!" не может стоять слева от оператора присваивания. Тогда, как он может являться леводопустимым выражением?

"WTF" = "Hello, world!"; // ошибка компиляции

l-value:

  • Выражения, непосредственно обозначающие объект, non-modifiable в случае const-квалификации. Например, имя переменной, параметра функции и т.п.
  • Выражения ссылочных типов. non-modifiable в случае const-квалификации. В частности, результат вызова функций, возвращающих объекты по ссылке; выражения, состоящие из имен ссылочных переменных; операции преобразования к ссылочному типу и т.д.
  • Результат встроенной операции разыменования (*) — lvalue указуемого типа; non-modifiable в случае const-квалификации.
  • Результат встроенных префиксных операций ++, --.
  • Имя функции.
  • Имя массива.
  • Строковые литералы.

r-value:

  • Выражения, обозначающие временные объекты. В частности, результат вызова функций, возвращающих объекты не по ссылке; результат встроенных операций +, -. > *, / и т.п.; явное создание временной переменной int() или C(); преобразования не к ссылочным типам и т.д.
  • Результат встроенной операции взятия адреса (&) — rvalue типа указатель.
  • Результат встроенных постфиксных операций ++, --.
  • Литералы, за исключением строковых (например, числовые литералы).
  • Константы перечислений.
Answer 1

Строковый литерал в С++ по всей строгости - это константа, и уже по одному этому участвовать в присвоении не может. Более того, в 2.14.5.12 сказано: The effect of attempting to modify a string literal is undefined.

Далее, по сути это - массив, а массив опять же в присвоении ну никак не участвует.

В 3.10.9 говорится: "If an expression can be used to modify the object to which it refers, the expression is called modifiable. A program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is ill-formed."

Наш же lvalue явно немодифицируемый.

Впрочем, само понятие lvalue имеет несколько иной смысл, чем приписываемый вами.

An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment expression) designates a function or an object.

Тут главное не то, что исторически они могли быть слева в выражении присваивания, а то, что это объект в памяти, от которого можно взять адрес. А получить адрес строкового литерала вполне можно, и в этом смысле это lvalue.

По-моему, так... (с) Пух

Answer 2

lvalue не значит, что такое выражение всегда может стоять слева от оператора присваивания. К примеру, пусть у Вас есть const int meConst = 5;, meConst в выражении meConst = 6; является lvalue, но пример всё равно собрать не удастся, т.к. нельзя изменять const int. То же самое со строковым литералом: да — это lvalue, нет — его нельзя модифицировать.

И небольшая, но релевантная цитата из C11[6.3.2.1]:

A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a constqualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a constqualified type.

READ ALSO
Добавить класс к ссылке

Добавить класс к ссылке

Есть менюНужно, чтобы при нажатии на любой из пунктов меню - он подчеркивался черной линией

330
Добавление jquery в yii2

Добавление jquery в yii2

ЗдравствуйтеЯ чет торможу, не могу найти в документации как подключить jquery в Yii2

373
Названия эффектов?

Названия эффектов?

Гуглю , но не нахожуПодскажите , как называются эффекты ?

330
Исправление popup

Исправление popup

При выборе пункта из меню, вместо того что бы нужный объект вставлялся в поле, меню закрываетсяПодскажите, что необходимо добавить в скрипт

232