Namespaces
Variants

cast operator

From cppreference.net

명시적 형 변환을 수행합니다

목차

구문

( type-name ) expression

여기서

type-name - void 타입이거나 임의의 스칼라 타입
expression - 임의의 표현식 으로 스칼라 타입 을 가짐 ( type-name void 인 경우에는 임의의 표현식 가능)

설명

만약 type-name void 인 경우, expression 은 부수 효과(side-effects)를 위해 평가되고 반환된 값은 폐기됩니다. 이는 expression 이 단독으로 표현식 문(expression statement) 으로 사용될 때와 동일합니다.

그렇지 않으면, type-name expression 의 정확한 타입인 경우, 아무 작업도 수행되지 않습니다 (단, expression 이 부동 소수점 타입을 가지고 해당 타입이 나타내는 것보다 더 큰 범위와 정밀도로 표현되는 경우는 제외합니다 – 아래 참조).

그렇지 않으면, expression 의 값이 다음과 같이 type-name 으로 명명된 타입으로 변환됩니다:

모든 대입에 의한 암시적 변환 이 허용됩니다.

암시적 변환 외에도 다음과 같은 변환들이 허용됩니다:

  • 모든 정수는 어떤 포인터 타입으로도 캐스트될 수 있습니다. NULL 같은 널 포인터 상수들(이는 캐스트가 필요하지 않음 )을 제외하면, 결과는 구현에 따라 정의되며, 올바르게 정렬되지 않을 수 있고, 참조된 타입의 객체를 가리키지 않을 수 있으며, 트랩 표현 일 수 있습니다.
  • 모든 포인터 타입은 어떤 정수 타입으로도 캐스트될 수 있습니다. 결과는 구현에 따라 정의되며, 심지어 널 포인터 값들(이들이 반드시 0 값을 결과로 내지 않음)에 대해서도 마찬가지입니다. 결과가 대상 타입으로 표현될 수 없는 경우, 동작은 정의되지 않습니다(부호 없는 정수들은 포인터로부터의 캐스트에 대해 모듈로 연산을 구현하지 않음).
  • 어떤 객체에 대한 포인터든 다른 어떤 객체에 대한 포인터로도 캐스트될 수 있습니다. 값이 대상 타입에 대해 올바르게 정렬되지 않은 경우, 동작은 정의되지 않습니다. 그렇지 않으면, 값이 원래 타입으로 다시 변환될 때 원래 값과 비교하여 같습니다. 객체에 대한 포인터가 어떤 문자 타입에 대한 포인터로 캐스트되는 경우, 결과는 객체의 가장 낮은 바이트를 가리키며 대상 타입의 sizeof까지 증가될 수 있습니다(다시 말해, 객체 표현 을 검사하거나 memcpy memmove 를 통해 복사본을 만드는 데 사용될 수 있음).
  • 어떤 함수에 대한 포인터든 다른 어떤 함수 타입에 대한 포인터로도 캐스트될 수 있습니다. 결과 포인터가 원래 타입으로 다시 변환되면 원래 값과 비교하여 같습니다. 변환된 포인터가 함수 호출을 만드는 데 사용되는 경우, 동작은 정의되지 않습니다(함수 타입들이 호환 가능 하지 않는 한).
  • 포인터들(객체 또는 함수) 사이에서 캐스팅할 때, 원래 값이 그 타입의 널 포인터 값인 경우, 결과는 대상 타입에 대한 올바른 널 포인터 값입니다.

어떤 경우든 (암시적 변환을 실행할 때와 동일 타입 캐스트 모두에서), 만약 expression type-name 이 부동 소수점 타입이고 expression 이 해당 타입이 나타내는 것보다 더 큰 범위와 정밀도로 표현된다면 (참조: FLT_EVAL_METHOD ), 범위와 정밀도는 대상 타입에 맞게 제거됩니다.

캐스트 표현식의 값 범주 는 항상 비-좌값입니다.

참고 사항

const , volatile , restrict , 그리고 _Atomic 한정자들은 lvalues 에만 영향을 미치기 때문에, cvr-한정 또는 atomic 타입으로의 캐스트는 해당 비한정 타입으로의 캐스트와 정확히 동일합니다.

void 로의 캐스팅은 때때로 사용되지 않는 결과에 대한 컴파일러 경고를 무시하는 데 유용합니다.

여기에 나열되지 않은 변환은 허용되지 않습니다. 특히,

  • 포인터와 부동 소수점 타입 간 변환은 존재하지 않습니다;
  • 함수 포인터와 객체 포인터( void * 포함) 간 변환은 존재하지 않습니다.

구현체가 intptr_t 및/또는 uintptr_t 를 제공하는 경우, 객체 타입에 대한 포인터( cv void 포함)를 이러한 타입으로의 캐스트는 항상 잘 정의됩니다. 그러나 함수 포인터에 대해서는 이것이 보장되지 않습니다.

(C99부터)

많은 컴파일러에서 함수 포인터와 객체 포인터 간의 변환을 확장 기능으로 허용하며, POSIX dlsym 함수의 일부 사용법에서 이를 기대합니다.

예제

#include <stdio.h>
int main(void)
{
    // 객체 표현식 검사는 캐스트의 정당한 사용 사례입니다
    const double d = 3.14;
    printf("The double %.2f (%a) is: ", d, d);
    for (size_t n = 0; n != sizeof d; ++n)
        printf("%02X ", ((unsigned char*)&d)[n]);
    // 경계 사례
    struct S { int x; } s;
    // (struct S)s; // 오류; 스칼라 타입이 아니며, 동일한 타입으로
                    // 캐스팅해도 아무런 변화가 없음
    (void)s; // 어떤 타입이든 void로 캐스트하는 것은 허용됨
}

출력:

The double 3.14 (0x1.91eb851eb851fp+1) is: 1F 85 EB 51 B8 1E 09 40

참고문헌

  • C23 표준 (ISO/IEC 9899:2024):
  • 6.5.5 캐스트 연산자 (p: 83-84)
  • C17 표준 (ISO/IEC 9899:2018):
  • 6.5.4 Cast 연산자 (p: 65-66)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.5.4 Cast 연산자 (p: 91)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.5.4 캐스트 연산자 (p: 81)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.3.4 Cast operators

참고 항목

C++ 문서 참조: 명시적 형 변환