스칼라 초기화

스칼라 초기화 (Scalar initialization)

변수를 만들 때 값을 정해 두는 것을 '초기화'라고 해요. 그중에서 스칼라 타입(단일 값)을 초기화하는 규칙을 이 페이지에서 살펴볼게요. 스칼라 초기화의 초기화자는 어떤 형태를 가져야 하는지가 핵심이에요.

출처: cppreference

본문

스칼라 타입의 객체를 초기화할 때, 초기화자는 단일 표현식이어야 해요.

스칼라(정수 타입 — 불리언·열거형 포함, 부동소수점 타입 — 복소수·허수 포함, 포인터 타입 — 함수 포인터 포함)의 초기화자는 단일 표현식 하나이거나, 선택적으로 중괄호 { }로 감싼 형태이거나, 빈 초기화자(empty initializer, C23)여야 해요:

= expression       (1)
= { expression }   (2)
= { }              (3)  (since C23)

1, 2) 표현식이 평가되고, 그 값이 객체의 타입에 할당하듯 변환된 뒤, 초기화되는 객체의 초기 값이 돼요.

  1. 객체는 빈 초기화(empty-initialized)돼요. 즉 산술·열거 타입이면 수치 0으로, 포인터 타입이면 null 포인터 값으로 초기화돼요.

참고 사항 (Notes)

할당하듯 변환하는 규칙 때문에, 변환할 타입을 정할 때 선언 타입의 const·volatile 한정자는 무시돼요.

초기화자를 쓰지 않을 때 적용되는 규칙은 초기화 문서를 봐요.

다른 모든 초기화와 마찬가지로, 정적 또는 스레드 로컬 저장 기간(static/thread-local storage duration)의 객체를 초기화할 때는 expression이 상수 표현식이어야 해요.

표현식은 콤마 연산자일 수 없어요 (괄호로 감싸지 않는 한). 최상위 콤마는 다음 선언자의 시작으로 해석되기 때문이에요.

부동소수점 타입의 객체를 초기화할 때, 자동 저장 기간(automatic storage duration)을 가진 객체에 대한 모든 계산은 마치 실행 시점에 일어난 것처럼 수행되고 현재 반올림 모드의 영향을 받아요. 부동소수점 오류는 math_errhandling에 명시된 대로 보고돼요. 정적·스레드 로컬 저장 기간의 객체에 대한 계산은 마치 컴파일 시점에 일어난 것처럼 수행되고 예외가 발생하지 않아요:

void f(void)
{
#pragma STDC FENV_ACCESS ON
    static float v = 1.1e75; // does not raise exceptions: static init

    float u[] = { 1.1e75 }; // raises FE_INEXACT
    float w = 1.1e75;       // raises FE_INEXACT

    double x = 1.1e75; // may raise FE_INEXACT (depends on FLT_EVAL_METHOD)
    float y = 1.1e75f; // may raise FE_INEXACT (depends on FLT_EVAL_METHOD)

    long double z = 1.1e75; // does not raise exceptions (conversion is exact)
}

예제 (Example)

#include <stdbool.h>
int main(void)
{
    bool b = true;
    const double d = 3.14;
    int k = 3.15; // conversion from double to int
    int n = {12}, // optional braces
       *p = &n,   // non-constant expression OK for automatic variable
       (*fp)(void) = main;
    enum {RED, BLUE} e = RED; // enumerations are scalar types as well
}

더 알아보기