C ++에서 다음 문구는 무엇을 의미합니까 : 0, 기본값 및 값 초기화?


190

C ++에서 다음 문구는 무엇을 의미합니까?

  • 제로 초기화,

  • 기본 초기화

  • 가치 초기화

C ++ 개발자가 알아야 할 사항은 무엇입니까?


1
이는 관련 (하지만 동일하지 않음)입니다 stackoverflow.com/questions/620137/...을
스티브 Jessop에게

20
더있다! 초기화의 전체 목록 : 값, 직접, 복사, 목록 (C ++ 11 새로운 소개), 집계, 참조, 0, 상수 및 기본값; en.cppreference.com/w/cpp/language/initialization의 : 예제와 함께 그들 모두의 목록
legends2k

답변:


65

한 가지 알아야 할 것은 '값 초기화'가 C ++ 2003 표준에 새로 도입되었다는 것입니다. 원래 1998 표준에는 존재하지 않습니다. 표준과 직접적인 정의에 대해서는 Kirill V. Lyadvinsky의 답변 을 참조하십시오 .

operator new이러한 유형의 초기화의 다른 동작과 시작될 때 및 c ++ 98과 C ++ 03이 다른 경우 에 대한 자세한 내용 은 동작에 대한 이전 답변을 참조하십시오 .

대답의 요점은 다음과 같습니다.

때로는 새로운 연산자가 반환 한 메모리가 초기화 될 수 있으며, 새로 업데이트하는 형식이 POD인지 또는 POD 멤버를 포함하고 컴파일러에서 생성 된 기본 생성자를 사용하는 클래스인지에 따라 달라지지 않을 수도 있습니다. .

  • C ++ 1998에는 0과 기본값의 두 가지 초기화 유형이 있습니다.
  • C ++ 2003에서는 세 번째 유형의 초기화 인 값 초기화가 추가되었습니다.

가장 적게 말하면, 그것은 다소 복잡하고 다른 방법이 시작될 때 미묘합니다.

확실히 알아야 할 사항은 MSVC가 VS 2008 (VC 9 또는 cl.exe 버전 15.x)에서도 C ++ 98 규칙을 따른다는 것입니다.

다음 스 니펫은 MSVC 및 Digital Mars가 C ++ 98 규칙을 따르는 반면 GCC 3.4.5 및 Comeau는 C ++ 03 규칙을 따릅니다.

#include <cstdio>
#include <cstring>
#include <new>

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

int main()
{
    char buf[sizeof(B)];
    std::memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    std::printf( "m  is %d\n", pB->m);
    return 0;
}

1
중요하지 int않지만 m()세 번째 줄 값은 m을 초기화합니다. 중요 변경하는 경우 int m;B m;. :)
Johannes Schaub-litb

마우스 오른쪽 - A그리고 C이 예에서 사용되지 않습니다 (그들은 링크 된 다른 대답 이월하고 있습니다). C ++ 98과 C ++ 03 은 방법 AC구성 방식을 설명 할 때 다른 용어를 사용 하지만 결과는 두 표준에서 동일합니다. struct B다른 동작 만 발생합니다.
Michael Burr

1
내가 의미하는 것은 C를로 변경 struct C { C() : m() {}; ~C(); B m; };하면 m.m0 이 될 것입니다. 그러나 mC ++ 03과 같이 기본 초기화 하면 m.mC ++ 98과 같이 초기화되지 않습니다.
Johannes Schaub-litb

1
이 기능을 처리 MSVC에 추가 흥미로운 의견 : stackoverflow.com/questions/3931312/...
브렌트 Bradburn

타입을 로컬 변수, 즉 스택에서 선언 할 때 어떤 초기화가 발생합니까?
André Puel

89

C ++ 03 표준 8.5 / 5 :

T 유형의 객체 를 0으로 초기화 하는
것은 다음을 의미합니다.
— T가 비 유니언 클래스 유형 인 경우 각 비 정적 데이터 멤버 및 각 기본 클래스 하위 오브젝트는 0으로 초기화됩니다.
— T가 공용체 유형 인 경우 객체의 첫 번째 명명 된 데이터 멤버는 0으로 초기화됩니다.
— T가 배열 유형 인 경우 각 요소는 0으로 초기화됩니다.
— T가 참조 유형 인 경우 초기화가 수행되지 않습니다.

T 유형의 객체 를 기본 초기화 하는 것은 다음을 의미합니다.
— T가 비 POD 클래스 유형 인 경우 (9 절), T에 대한 기본 생성자가 호출됩니다 (T에 액세스 가능한 기본 생성자가없는 경우 초기화는 잘못된 형식입니다).
— T가 배열 유형 인 경우 각 요소는 기본적으로 초기화됩니다.
— 그렇지 않으면 객체가 0으로 초기화됩니다.

T 유형의 객체 를 값으로 초기화 하는 것은 다음을 의미합니다.
— T가 사용자가 선언 한 생성자 (12.1)를 가진 클래스 유형 (9 항) 인 ​​경우 T의 기본 생성자가 호출되며 T는 초기화되지 않습니다. 액세스 가능한 기본 생성자가 없습니다);
— T가 사용자 선언 생성자가없는 비 유니언 클래스 유형 인 경우, T의 모든 비 정적 데이터 멤버 및 기본 클래스 구성 요소는 값으로 초기화됩니다.
— T가 배열 유형 인 경우 각 요소는 값으로 초기화됩니다.
— 그렇지 않으면, 객체는 0으로 초기화된다

참조 유형 엔티티의 기본 초기화 또는 값 초기화를 호출하는 프로그램이 잘못 구성되었습니다. T가 cv-qualified 유형 인 경우 cv-unqualified 버전의 T는 zero-initialization, default-initialization 및 value-initialization의 정의에 사용됩니다.


18
C ++ 11에서는 구식 일 수 있습니다. cppreference.com에 따르면 기본 초기화 멤버를 0 으로 초기화 하지 않습니다 (값 초기화 만).
Alexei Sholik

3
@android는 중요한 점을 제기했는데 다른 곳에서는 대답을 볼 수 없으므로 새로운 질문을했습니다. stackoverflow.com/questions/22233148/…
Adrian McCarthy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.