본문 바로가기

프로그래밍 언어/C++

glvalue-to-prvalue conversion에 대해

반응형

conversion의 설계 개념

C++의 conversion를 정의할 때, 직교하는 3 요소, value category, cv-qualification, data representation를 설계 개념으로 사용한다. conversion를 설계할 때, 요소 중 하나만을 변형하고, 다른 요소를 변형하지 않는다. 어떤 이유로, 예를 들어 하위 호환성을 위해, 설계 개념을 위반할 때는 스펙 문서는 관련된 특수 조항을 별도로 명시한다.

glvalue-to-prvalue conversion

value category 요소를 변형하기 위해 설계한 conversion이다. value category 요소만 변경하기 때문에, exact match rank로 분류된다. 또한 일반적으로 cv-qualification이나 data representation를 변경하지 않는다.

non-function이나 non-array 타입 T의 glvalue category에서 T의 prvalue category로 변환한다. glvalue-to-prvalue conversion이 조금 더 정확한 용어지만, value category를 C++처럼 세밀하게 구분하지 않는 C 언어에서 처음 정의한 용어를, C++에서 현시점까지는 그대로 사용한다. value category만을 변경하지만, T 타입은 complete type이어야 한다. T 타입이 incomplete type일 때, glvalue-to-prvalue conversion를 사용하면, 컴파일 오류가 발생한다.

non-class 타입 T의 cv glvalue category를 T의 non-cv prvalue category로 변경한다. 즉, C 언어와의 호환성을 위해 cv-qualification를 함께 변경하는 것을 허용한다. std::nullptr_t 타입 T의 cv glvalue category를 타입 T의 non-cv prvalue category로 변경한다. 즉, 기존 null pointer constant와의 호환성 문제를 해결하기 cv-qualification를 함께 변경하는 것을 허용한다. 다른 경우, glvalue-to-prvalue conversion는 다른 요소를 변경하지 않는다.

invalid pointer value를 갖고 있는 glvalue category에 대한, glvalue-to-prvalue conversion는 implementation-defined behavior를 갖는다. 즉 invalid pointer value에 대한, result prvalue category는 컴파일러 구현자마다 다르게 정의할 수 있다. 그 외 valid value를 갖고 있는 glvalue category에 대한, result prvalue category는 object가 갖고 있는 valid value다. 그 외 경우는 undefined behavior다.

class 타입 T의 result prvalue categoryglvalue category로부터 copy-initialization한다.

struct S { int n; };
auto f() {
    S x{ 1 };
    constexpr S y{ 2 };
    return [&](bool b) { return (b ? y : x).n; };
}
auto g = f();
int m = g(false); // undefined behavior: access of x.n outside its lifetime
int n = g(true);  // OK, does not access y.n

return 연산자에 대해서는 언급하지 않았지만, 두 return 모두에서 glvalue-to-prvalue conversion 작동한다. 두 return 구문 모두에서 xvalue category를 반환한다. auto g, int m, int n 등을 초기화할 때, prvalue category를 요구한다. 즉 모든 초기화 구문에서 xvalue category에서 prvalue category가 요구한다. glvalue-to-prvalue conversion 작동한다.

prvalue category를 만든 객체가 constexpr 객체일 때 constexpr 객체를 odr-used한 것이 아님으로 valid value 상태를 유지한다. 그에 비해 constexpr 객체가 아닐 때, odr-used하기 때문에, 스코프를 벗어나면 invalid value의 xvalue category로부터 prvalue category 변환이 이루어진다. 따라서 undefined behavior다.

반응형