Expressions
표현식은 연산을 지정하는 일련의 연산자 와 그 피연산자 로 구성됩니다.
표현식 평가는 결과를 생성할 수 있으며(예: 2 + 2 의 평가는 4 라는 결과를 생성함), 부수 효과를 발생시킬 수도 있습니다(예: std:: printf ( "%d" , 4 ) 의 평가는 표준 출력에 문자 '4' 을 인쇄함).
각 C++ 표현식은 두 가지 독립적인 속성으로 특징지어집니다: 타입과 값 범주.
목차 |
일반
- 값 카테고리 (lvalue, rvalue , glvalue, prvalue, xvalue (C++11부터) )는 표현식을 값에 따라 분류합니다
- 평가 순서 는 인수와 하위 표현식의 중간 결과가 얻어지는 순서를 지정합니다
연산자
| 일반 연산자 | ||||||
|---|---|---|---|---|---|---|
| assignment |
increment
decrement |
arithmetic | logical | comparison |
member
access |
other |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
함수 호출
a ( ... ) |
|
콤마
a, b |
||||||
|
조건부 연산자
a ? b : c |
||||||
| 특수 연산자 | ||||||
|
static_cast
관련된 타입 간 변환을 수행
|
||||||
- 연산자 우선순위 는 연산자가 피연산자에 결합되는 순서를 정의합니다
- 대체 표현 은 일부 연산자에 대한 대체 표기법입니다
- 연산자 오버로딩 은 사용자 정의 클래스에서 연산자의 동작을 지정할 수 있게 합니다.
변환
- 표준 변환 한 타입에서 다른 타입으로의 암시적 변환
-
const_cast변환 -
static_cast변환 -
dynamic_cast변환 -
reinterpret_cast변환 - 명시적 캐스트 C-스타일 캐스트 표기법과 함수-스타일 표기법을 사용한 변환
- 사용자 정의 변환 사용자 정의 클래스로부터의 변환을 지정할 수 있게 함
메모리 할당
- new expression 동적으로 메모리를 할당합니다
- delete expression 동적으로 메모리를 해제합니다
기타
- 상수 표현식 은 컴파일 타임에 평가될 수 있으며 컴파일 타임 컨텍스트(템플릿 인자, 배열 크기 등)에서 사용될 수 있습니다
-
sizeof -
alignof -
typeid - throw-표현식
기본 표현식
모든 연산자의 피연산자는 다른 표현식이나 기본 표현식일 수 있습니다(예: 1 + 2 * 3 에서 operator+의 피연산자는 하위 표현식 2 * 3 과 기본 표현식 1 입니다).
기본 식(primary expressions)은 다음 중 하나입니다:
-
this - 리터럴 (예: 2 또는 "Hello, world" )
-
식별자 표현식, 포함:
- 적절히 선언된 비한정 식별자 (예: n 또는 cout ),
- 적절히 선언된 한정 식별자 (예: std::string::npos ), 및
- 선언자 에서 선언될 식별자
| (C++26부터) |
| (C++11부터) | |
| (C++17부터) | |
| (C++20부터) |
괄호 안의 모든 표현식은 기본 표현식으로도 분류됩니다: 이는 괄호가 모든 연산자보다 높은 우선순위를 가짐을 보장합니다. 괄호는 값, 타입, 그리고 값 범주를 보존합니다.
리터럴
리터럴은 소스 코드에 내장된 상수 값을 나타내는 C++ 프로그램의 토큰입니다.
-
- char 또는 wchar_t
|
(C++11부터) |
|
(C++20부터) |
-
- const char [ ] 또는 const wchar_t [ ]
|
(C++11부터) |
|
(C++20부터) |
- 불리언 리터럴 은 bool 타입의 값들, 즉 true 과 false 입니다
|
(C++11부터) |
완전-표현식
구성 요소 표현식 은 다음과 같이 정의됩니다:
- 표현식의 구성 표현식은 해당 표현식입니다.
- brace-enclosed initializer list 또는 (괄호로 둘러싸인) expression list의 구성 표현식은 해당 리스트 요소들의 구성 표현식들입니다.
-
=로 시작하는 initializer 의 구성 표현식은 initializer-clause 의 구성 표현식들입니다.
int num1 = 0; num1 += 1; // 사례 1: "num += 1"의 구성 표현식은 "num += 1"입니다 int arr2[2] = {2, 22} // 사례 2: "{2, 22}"의 구성 표현식은 // "2"와 "22"입니다 // 사례 3: "= {2, 22}"의 구성 표현식은 // "{2, 22}"의 구성 표현식입니다 // (즉, "2"와 "22"입니다)
E 표현식의 직접적인 하위 표현식들 은 다음과 같습니다
- E 피연산자들의 구성 표현식,
|
(C++14부터) |
|
(C++11부터) |
- E 가 암시적으로 호출하는 모든 함수 호출, 또는
- E 가 함수 호출이거나 암시적으로 함수를 호출하는 경우, 호출에서 사용된 각 기본 인자 의 구성 표현식.
표현식 E 의 부분식(subexpression) 은 E 의 직접적인 부분식이거나, E 의 직접적인 부분식의 부분식입니다. 람다 표현식의 "함수 본체"에 나타나는 표현식들은 람다 표현식의 부분식이 아니라는 점에 유의하십시오. (C++11부터)
다음 표현식들은 full-expressions 입니다:
| (C++20부터) |
- simple declarations 또는 member initializers 의 선언자, 초기화자의 구성 표현식을 포함
- 수명이 연장되지 않은 임시 객체를 제외한 객체의 lifetime 종료 시 생성된 destructors 호출
|
(C++26부터) |
- 다른 어떤 표현식의 하위 표현식이 아니고 다른 어떤 완전 표현식의 일부가 아닌 표현식
언어 구조가 함수의 암시적 호출을 생성하도록 정의된 경우, 언어 구조의 사용은 이 정의의 목적을 위해 표현식으로 간주됩니다. 표현식이 나타나는 언어 구조의 요구 사항을 충족시키기 위해 표현식의 결과에 적용되는 변환도 전체 표현식의 일부로 간주됩니다.
초기화자의 경우, 엔티티의 초기화를 수행하는 것 (집합체의 기본 멤버 초기화자를 평가하는 것을 포함) (C++14부터) 또한 완전 표현식(Full-expression)의 일부로 간주됩니다.
잠재적으로 평가되는 표현식
|
표현식은 다음의 경우를 제외하고 잠재적으로 평가됩니다 : |
(C++11까지) | ||
|
다음 피연산자들은 평가되지 않는 피연산자 이며, 평가되지 않습니다:
표현식은 다음의 경우를 제외하고 잠재적으로 평가됩니다 :
|
(C++11부터) |
잠재적으로 평가되는 표현식은 ODR-use 입니다.
|
이 섹션은 불완전합니다
이유: 평가되지 않은 피연산자의 예시 |
폐기 값 표현식
폐기값 표현식(discarded-value expression) 은 부수 효과(side-effects)만을 위해 사용되는 표현식입니다. 이러한 표현식에서 계산된 값은 폐기됩니다. 이러한 표현식에는 모든 표현식 문(expression statement) 의 전체 표현식(full-expression), 내장 쉼표 연산자(built-in comma operator)의 왼쪽 피연산자, 또는 void 타입으로 캐스팅하는 캐스트 표현식(cast-expression)의 피연산자가 포함됩니다.
배열-대-포인터 및 함수-대-포인터 변환은 폐기된-값 표현식에 의해 계산된 값에 절대 적용되지 않습니다. lvalue-대-rvalue 변환은 오직 표현식이 volatile-qualified glvalue이고 다음 형태 중 하나를 가질 경우에만 적용됩니다 (내장 의미 필요, 가능하면 괄호로 묶인):
- id-expression,
- array subscript expression,
- class member access expression,
- indirection,
- pointer-to-member operation,
- conditional expression where both the second and the third operands are one of these expressions,
- comma expression where the right operand is one of these expressions.
또한, lvalue가 volatile 한정 클래스 타입인 경우, 결과로 생성되는 rvalue 임시 객체를 초기화하기 위해 volatile 복사 생성자가 필요합니다.
|
표현식이 void가 아닌 prvalue인 경우(발생했을 수 있는 lvalue-to-rvalue 변환 후), temporary materialization 이 발생합니다.
컴파일러는
void
로의 캐스트를 제외한 표현식이
|
(since C++17) |
표현식 동등성(Expression-equivalence)여러 표현식 e1 , e2 , ..., eN 은 다음 모든 조건을 만족할 때 표현식-동등(expression-equivalent) 하다고 합니다:
e1 이 e2 와 표현식-동등(expression-equivalent)하다 는 것은 e1 과 e2 가 표현식-동등한 것과 필요충분조건이며 (이는 e2 가 e1 와도 표현식-동등함을 의미합니다). |
(C++20부터) |
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 1054 | C++98 |
volatile 변수에 값을 할당하면 할당 결과에
적용되는 lvalue-to-rvalue 변환으로 인해 불필요한 읽기가 발생할 수 있음 |
discarded-value 표현식을 도입하고
이 경우를 변환이 필요한 경우 목록에서 제외함 |
| CWG 1343 | C++98 |
집합체 초기화에서 소멸자 호출 순서가
불충분하게 명세됨 |
집합체 초기화의 full-expression이
명확하게 명세됨 |
| CWG 1383 | C++98 |
discarded-value 표현식에 lvalue-to-rvalue
변환이 적용되는 표현식 목록에 오버로드된 연산자도 포함됨 |
기본 의미를 가진 연산자만
포함하도록 수정 |
| CWG 1576 | C++11 |
discarded-value volatile xvalue 표현식에
lvalue-to-rvalue 변환이 적용되지 않음 |
이 경우에도 변환을
적용함 |
| CWG 2249 | C++98 |
선언자에서 선언될 식별자가
id-expression이 아니었음 |
id-expression으로 명시 |
| CWG 2431 | C++11 |
참조에 바인딩된 임시 객체의 소멸자 호출이
full-expression이 아니었음 |
full-expression으로 명시 |
참고 항목
|
C 문서
for
Expressions
|