cast operator
명시적 형 변환을 수행합니다
목차 |
구문
(
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++ 문서
참조:
명시적 형 변환
|