Namespaces
Variants

Value categories

From cppreference.net

C 언어의 각 표현식 (인자를 가진 연산자, 함수 호출, 상수, 변수명 등)은 두 가지 독립적인 속성으로 특징지어집니다: 타입 값 카테고리 입니다.

모든 표현식은 세 가지 값 범주 중 하나에 속합니다: lvalue, 비-lvalue 객체(rvalue), 그리고 함수 지정자.

목차

Lvalue 표현식

Lvalue 표현식은 객체 타입 을 가지며 void 타입이 아닌, 잠재적으로 객체 를 지정하는 모든 표현식입니다(실제로 평가 시 객체를 지정하지 않는 lvalue의 동작은 정의되지 않음). 다른 말로 하면, lvalue 표현식은 객체 식별성  으로 평가됩니다. 이 값 범주의 이름("왼쪽 값")은 역사적인 것으로, CPL 프로그래밍 언어에서 할당 연산자의 왼쪽 피연산자로 lvalue 표현식을 사용한 데서 비롯되었습니다.

Lvalue 표현식은 다음과 같은 lvalue 컨텍스트  에서 사용될 수 있습니다:

lvalue 표현식이 sizeof , _Alignof 또는 위에 나열된 연산자 이외의 다른 상황에서 사용될 경우, 모든 완전한 타입의 non-array lvalue는 lvalue conversion 을 거치며, 이는 객체의 값을 해당 위치에서 메모리 로드하는 것을 모델링합니다. 마찬가지로, array lvalue는 sizeof , _Alignof , 주소 연산자 또는 문자열 리터럴로부터의 배열 초기화 이외의 다른 상황에서 사용될 때 array-to-pointer conversion 을 거칩니다.

const / volatile / restrict 한정자와 atomic 타입의 의미론은 lvalues에만 적용됩니다 (lvalue 변환은 한정자를 제거하고 atomicity를 제거합니다).

다음 표현식들은 lvalue입니다:

  • 식별자 (함수 명명된 매개변수 포함), 객체를 지정하도록 선언된 경우 (함수나 열거형 상수가 아닌)
  • 문자열 리터럴
  • (C99) 복합 리터럴
  • 괄호로 묶인 표현식 (괄호를 제거한 표현식이 lvalue인 경우)
  • 멤버 접근 (점) 연산자의 결과 (왼쪽 피연산자가 lvalue인 경우)
  • 포인터를 통한 멤버 접근 -> 연산자의 결과
  • 간접 참조 (단항 * ) 연산자를 객체 포인터에 적용한 결과
  • 첨자 연산자 ( [] )의 결과

수정 가능한 lvalue 표현식

수정 가능한 lvalue const -qualified가 아닌 완전한 비배열 타입의 모든 lvalue 표현식이며, 구조체/공용체인 경우 재귀적으로 const -qualified된 멤버를 갖지 않는 것을 말합니다.

수정 가능한 좌측값(lvalue) 표현식만이 증감 연산자의 인수로, 그리고 대입 연산자 및 복합 대입 연산자의 좌변 인수로 사용될 수 있습니다.

비-좌측값 객체 표현식

rvalues  로 알려진 비-좌측값 객체 표현식은 객체를 지정하지 않고, 객체 식별성이나 저장 위치가 없는 값을 나타내는 객체 타입의 표현식입니다. 비-좌측값 객체 표현식의 주소는 취할 수 없습니다.

다음 표현식들은 좌변값이 아닌 객체 표현식입니다:

  • 정수형, 문자형, 부동소수점 상수
  • lvalue를 반환하도록 명시되지 않은 모든 연산자, 포함하여
  • 모든 함수 호출 표현식
  • 모든 캐스트 표현식 (참고: 유사하게 보이는 복합 리터럴은 lvalue입니다)
  • 비-lvalue 구조체/공용체에 적용된 멤버 접근 연산자 (점), f ( ) . x , ( x, s1 ) . a , ( s1 = s2 ) . m
  • 모든 산술, 관계, 논리, 비트 연산자의 결과
  • 증감 연산자의 결과 (참고: 전위 형태는 C++에서 lvalue입니다)
  • 대입 연산자의 결과 (참고: C++에서 또한 lvalue입니다)
  • 조건 연산자 (참고: 두 번째와 세 번째 피연산자가 동일한 타입의 lvalue인 경우 C++에서 lvalue입니다)
  • 쉼표 연산자 (참고: 두 번째 피연산자가 lvalue인 경우 C++에서 lvalue입니다)
  • 주소 연산자, 단항 * 연산자의 결과에 적용되어 중화된 경우에도

특별한 경우로, void 타입의 표현식은 표현이 없고 저장 공간이 필요 없는 값을 생성하는 비-좌측값 객체 표현식으로 간주됩니다.

배열 타입의 멤버(아마도 중첩된)를 가진 struct/union rvalue는 실제로 temporary lifetime 을 가진 객체를 지정한다는 점에 유의하십시오. 이 객체는 배열 멤버를 인덱싱하거나 배열 멤버의 array-to-pointer 변환을 통해 얻은 포인터를 역참조하여 형성된 lvalue 표현식을 통해 접근할 수 있습니다.

(since C99)

함수 지정자 표현식

함수 지정자(함수 선언으로 도입된 식별자)는 함수 타입의 표현식입니다. 주소 연산자, function declaration )는 함수 타입의 표현식입니다. 주소 연산자, sizeof , 그리고 _Alignof (마지막 두 개는 함수에 적용될 때 컴파일 오류를 생성함)를 제외한 다른 모든 문맥에서 사용될 때, 함수 지정자는 항상 함수를 가리키는 비左값(non-lvalue) 포인터로 변환됩니다. 함수 호출 연산자는 함수 지정자 자체가 아닌 함수 포인터에 대해 정의된다는 점에 유의하십시오.

참조문헌

  • C23 표준 (ISO/IEC 9899:2024):
  • 6.3.2.1 Lvalues, arrays, and function designators (p: 48-49)
  • C17 표준 (ISO/IEC 9899:2018):
  • 6.3.2.1 Lvalues, arrays, and function designators (p: 40)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.3.2.1 Lvalues, arrays, and function designators (p: 54-55)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.3.2.1 Lvalues, arrays, and function designators (p: 46)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.2.2.1 Lvalues 및 함수 지정자

참고 항목

C++ documentation for Value categories