C에서는 구조체를 초기화하는 몇 가지 방법이 있습니다:
struct Point { int x, y; }; struct Point p = {10, 20};
필드는 선언된 순서대로 초기화됩니다.
struct Point p = {.y = 20, .x = 10};
필드를 임의의 순서로 초기화할 수 있습니다.
struct Rect { int x, y, w, h; } r = {1, 2}; // w와 h는 0
struct Color { int r, g, b; }; struct Pixel { struct Point pos; struct Color col; }; struct Pixel px = {{10,20}, {255,0,0}};
이름 있는 초기화는 오류를 피하는 데 도움이 됩니다:
struct Pixel px = {.col = {.r = 255, .g = 0, .b = 0}};
주의 사항:
질문: 구조체를 초기화할 때 모든 필드를 명시하지 않으면 자동 로컬 변수로 선언된 구조체는 어떻게 됩니까?
예상되는 잘못된 답변: "나머지 필드는 항상 0이 됩니다."
올바른 답변: 자동 (로컬) 변수는 명시적으로 초기화되지 않으면 초기화되지 않은 값을 유지합니다. 부분 초기화는 명시적으로 지정된 필드만 초기화하며, 나머지는 정의되지 않은 값이 됩니다 (단, = {...}로 초기화하는 경우 나머지는 정적/전역 구조체에 대해서만 0이 됩니다).
예:
void foo() { struct Point { int x, y, z; } p = {1}; // p.x == 1, p.y와 p.z == 0 (오직 = {1};를 통해서만) }
이야기
그래픽 엔진 프로젝트에서 정점 구조체의 시작 부분에 필드를 추가했지만, 다른 모듈에서 객체 초기화 방식을 다시 검토하지 않았습니다. 그 결과, 절반의 모듈이 색상이나 좌표를 잘못 초기화하여 렌더링 결함이 나타났습니다.
이야기
비디오 처리기에서 구조체가 중첩 포인터를 부분적으로 초기화하여 = {0}으로 설정했습니다. 이는 전역 변수에 대해서는 올바르지만 로컬 변수에는 그렇지 않았습니다. 결국 포인터는 '쓰레기'를 포함하게 되어 유효하지 않은 주소로 작업하게 되었고, 이는 추적하기 어려운 충돌을 초래했습니다.
이야기
대규모 구조체에 새로운 필드를 추가할 때 저자들이 오래된 코드에서 순서 기반 초기화를 업데이트하지 않았습니다. 필드와 초기화자의 순서가 일치하지 않아 중요한 변수가 부정확한 값을 받게 되었습니다. 원인은 구조체 감사와 이름 있는 초기화 도입을 통해 밝혀졌습니다.