Namespaces
Variants

const type qualifier

From cppreference.net

C 타입 시스템 의 각 개별 타입에는 해당 타입의 여러 한정된(qualified) 버전이 존재하며, 이는 const , volatile , 그리고 객체 타입에 대한 포인터의 경우 restrict 한정자 중 하나, 둘, 또는 모두 세 가지에 해당합니다. 이 페이지는 const 한정자의 효과에 대해 설명합니다.

const로 한정된 타입으로 선언된 객체들은 컴파일러에 의해 읽기 전용 메모리에 배치될 수 있으며, const 객체의 주소가 프로그램 내에서 전혀 사용되지 않는 경우 아예 저장되지 않을 수도 있습니다.

const로 한정된 타입의 객체를 수정하려는 모든 시도는 정의되지 않은 동작을 초래합니다.

const int n = 1; // const-qualified 타입의 객체
int* p = (int*)&n;
*p = 2; // 정의되지 않은 동작

const 의미론은 lvalue 표현식에만 적용됩니다; const lvalue 표현식이 lvalue를 요구하지 않는 문맥에서 사용될 때마다, 그 const 한정자는 사라집니다(volatile 한정자가 있는 경우, 그것은 사라지지 않는다는 점에 유의하세요).

const 한정 타입의 객체를 지정하는 lvalue 표현식과, 적어도 하나의 const 한정 타입 멤버(재귀적으로 포함된 집합체나 공용체의 멤버 포함)를 가진 구조체 또는 공용체 타입의 객체를 지정하는 lvalue 표현식은 수정 가능한 lvalue 가 아닙니다. 특히, 이들은 대입할 수 없습니다:

const int n = 1; // const 타입의 객체
n = 2; // 오류: n의 타입은 const로 한정됨
int x = 2; // 한정되지 않은 타입의 객체
const int* p = &x;
*p = 3; // 오류: lvalue *p의 타입은 const로 한정됨
struct {int a; const int b; } s1 = {.b=1}, s2 = {.b=2};
s1 = s2; // 오류: s1의 타입은 한정되지 않았지만 const 멤버를 가지고 있음

const 한정 구조체 또는 공용체 타입의 멤버는 해당 타입이 속한 한정을 획득합니다( . 연산자나 -> 연산자를 사용하여 접근할 때 모두).

struct s { int i; const int ci; } s;
// s.i의 타입은 int, s.ci의 타입은 const int
const struct s cs;
// cs.i와 cs.ci의 타입은 모두 const int

배열 타입이 const 타입 한정자( typedef 사용을 통해)로 선언되면, 배열 타입 자체는 const로 한정되지 않지만 그 요소 타입은 const로 한정됩니다.

(until C23)

배열 타입과 그 요소 타입은 항상 동일하게 const로 한정된 것으로 간주됩니다.

(since C23)
typedef int A[2][3];
const A a = {{4, 5, 6}, {7, 8, 9}}; // const int의 배열의 배열
int* pi = a[0]; // 오류: a[0]의 타입은 const int*
void *unqual_ptr = a; // C23까지는 OK; C23 이후부터는 오류
// 참고: clang은 C89-C17 모드에서도 C++/C23 규칙을 적용함

함수 타입이 const 타입 한정자( typedef 사용을 통해)로 선언되면, 동작은 정의되지 않습니다.

함수 선언에서 const 키워드는 함수 매개변수의 배열 타입을 선언하는 데 사용되는 대괄호 안에 나타날 수 있습니다. 이것은 배열 타입이 변환되는 포인터 타입을 한정합니다.

다음 두 선언은 동일한 함수를 선언합니다:

void f(double x[const], const double y[const]);
void f(double * const x, const double * const y);
(since C99)

const로 한정된 복합 리터럴은 반드시 별개의 객체를 지정하지 않을 수 있습니다; 이들은 동일하거나 중복되는 표현을 갖는 다른 복합 리터럴 및 문자열 리터럴과 저장 공간을 공유할 수 있습니다.

const int* p1 = (const int[]){1, 2, 3};
const int* p2 = (const int[]){2, 3, 4}; // the value of p2 may equal p1+1
_Bool b = "foobar" + 3 == (const char[]){"bar"}; // the value of b may be 1
(C99부터)

비-const 타입에 대한 포인터는 동일하거나 호환되는 타입의 const 한정 버전에 대한 포인터로 암시적으로 변환될 수 있습니다. 역변환은 캐스트 표현식이 필요합니다.

int* p = 0;
const int* cp = p; // OK: 한정자 추가 (int에서 const int로)
p = cp; // Error: 한정자 제거 (const int에서 int로)
p = (int*)cp; // OK: 캐스트

T 에 대한 포인터의 포인터는 const T 에 대한 포인터의 포인터로 변환할 수 없음에 유의하십시오. 두 타입이 호환되려면 해당 한정자(qualifications)가 동일해야 합니다.

char *p = 0;
const char **cpp = &p; // 오류: char*와 const char*는 호환되지 않는 타입입니다
char * const *pcp = &p; // OK, 한정자 추가 (char*에서 char*const로)

목차

키워드

const

참고 사항

C는 C++로부터 const 한정자를 채택했지만, C++과 달리 C에서 const 한정 타입의 표현식들은 상수 표현식 이 아닙니다; 이들은 case 레이블로 사용되거나 static thread 저장 기간 객체, enumerators , 또는 bit-field 크기를 초기화하는 데 사용될 수 없습니다. 이들이 array 크기로 사용될 때, 결과 배열들은 VLA입니다.

참조문헌

  • C17 표준 (ISO/IEC 9899:2018):
  • 6.7.3 타입 한정자 (p: 87-90)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.7.3 타입 한정자 (p: 121-123)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.7.3 타입 한정자 (p: 108-110)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 6.5.3 Type qualifiers

참고 항목

C++ documentation for cv ( const and volatile ) type qualifiers