Spec-Zone.ru › C

Категории значений

Каждое выражение в C (оператор с его аргументами, вызов функции, константа, имя переменной и т. д.) характеризуется двумя независимыми свойствами: типом и категорией значения.

Каждое выражение относится к одной из трёх категорий значений: lvalue, объект, не являющийся lvalue (rvalue), или обозначатель функции.

Выражения lvalue

Выражение lvalue — это любое выражение с объектным типом, отличным от типа void, которое потенциально обозначает объект (поведение не определено, если при вычислении lvalue фактически не обозначает объект). Другими словами, выражение lvalue вычисляется в идентичность объекта . Название этой категории значений («левое значение») имеет историческое происхождение и отражает использование выражений lvalue в качестве левого операнда оператора присваивания в языке программирования CPL.

Выражения lvalue можно использовать в следующих контекстах lvalue :

  • в качестве операнда оператора взятия адреса (кроме случаев, когда lvalue обозначает битовое поле или было объявлено с классом памяти register).
  • в качестве операнда операторов инкремента и декремента с префиксной или постфиксной формой.
  • в качестве левого операнда оператора доступа к члену (точка).
  • в качестве левого операнда операторов присваивания и составного присваивания.

Если выражение lvalue используется в любом контексте, кроме sizeof, _Alignof или перечисленных выше операторов, к lvalue не-массивов любого полного типа применяется преобразование lvalue, моделирующее загрузку значения объекта из памяти по месту его расположения. Аналогично, к lvalue-массивам применяется преобразование массива в указатель при использовании в любом контексте, кроме sizeof, _Alignof, оператора взятия адреса или инициализации массива строковым литералом.

Семантика квалификаторов const/volatile/restrict и атомарных типов применяется только к lvalue (преобразование lvalue удаляет квалификаторы и атомарность).

Следующие выражения являются lvalue:

  • идентификаторы, включая именованные параметры функций, если они были объявлены как обозначающие объекты (а не функции или константы перечисления)
  • строковые литералы
  • (C99) составные литералы
  • выражение в скобках, если выражение без скобок является lvalue
  • результат оператора доступа к члену (точка), если его левый аргумент является lvalue
  • результат доступа к члену через оператор -> указателя
  • результат оператора разыменования (унарного *), применённого к указателю на объект
  • результат оператора индексирования ([])

Изменяемые выражения lvalue

Изменяемое lvalue — это любое выражение lvalue полного типа, не являющегося типом массива и не квалифицированного как const; если это структура или объединение, оно также не должно рекурсивно содержать членов, квалифицированных как const.

Только изменяемые выражения lvalue можно использовать в качестве аргументов операторов инкремента/декремента и левых аргументов операторов присваивания и составного присваивания.

Выражения-объекты, не являющиеся lvalue

Известные как rvalue , выражения-объекты, не являющиеся lvalue, — это выражения объектных типов, которые не обозначают объекты, а представляют значения, не имеющие идентичности объекта или места хранения. Взять адрес выражения-объекта, не являющегося lvalue, нельзя.

Следующие выражения являются выражениями-объектами, не являющимися lvalue:

  • целочисленные, символьные и вещественные константы
  • все операторы, для которых не указано, что они возвращают lvalue, в том числе
    • любое выражение вызова функции
    • любое выражение приведения типа (обратите внимание, что составные литералы, похожие на них, являются lvalue)
    • оператор доступа к члену (точка), применённый к структуре/объединению, не являющейся lvalue, f().x, (x, s1).a, (s1 = s2).m
    • результаты всех арифметических, реляционных, логических и побитовых операторов
    • результаты операторов инкремента и декремента (примечание: префиксные формы являются lvalue в C++)
    • результаты операторов присваивания (примечание: в C++ они также являются lvalue)
    • условный оператор (примечание: в C++ он является lvalue, если второй и третий операнды — lvalue одного типа)
    • оператор запятая (примечание: в C++ он является lvalue, если таким является второй операнд)
    • оператор взятия адреса, даже если его действие нейтрализуется применением к результату унарного оператора *

В особом случае выражения типа void считаются выражениями-объектами, не являющимися lvalue, которые дают значение без представления и не требующее хранения.

Обратите внимание, что rvalue структуры/объединения, содержащая член (возможно, вложенный) типа массива, действительно обозначает объект с временным временем жизни. Доступ к этому объекту возможен через выражения lvalue, образующиеся при индексировании члена-массива или при разыменовании указателя, полученного в результате преобразования члена-массива из массива в указатель.

(начиная с C99)

Выражение-обозначатель функции

Обозначатель функции (идентификатор, введённый объявлением функции) — это выражение функционального типа. При использовании в любом контексте, кроме оператора взятия адреса, sizeof и _Alignof (последние два оператора приводят к ошибкам компиляции при применении к функциям), обозначатель функции всегда преобразуется в указатель на функцию, не являющийся lvalue. Обратите внимание, что оператор вызова функции определён для указателей на функции, а не для самих обозначателей функций.

Источники

  • Стандарт C23 (ISO/IEC 9899:2024):
    • 6.3.2.1 Lvalues, arrays, and function designators (с. 48–49)
  • Стандарт C17 (ISO/IEC 9899:2018):
    • 6.3.2.1 Lvalues, arrays, and function designators (с. 40)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 6.3.2.1 Lvalues, arrays, and function designators (с. 54–55)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 6.3.2.1 Lvalues, arrays, and function designators (с. 46)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
    • 3.2.2.1 Lvalues and function designators

См. также

Документация C++ для категорий значений

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/language/value_category

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API