programing

C 및 C++ : 자동구조 부분 초기화

nicescript 2022. 8. 23. 23:24
반응형

C 및 C++ : 자동구조 부분 초기화

예를 들어,somestruct에는 3개의 정수 멤버가 있기 때문에 항상 C(또는 C++) 함수로 이 작업을 수행해도 괜찮다고 생각했습니다.

somestruct s = {123,};

첫 번째 멤버는 123으로 초기화되고 마지막 2명은 0으로 초기화됩니다.자동 배열, 쓰기에서도 같은 작업을 자주 합니다.int arr[100] = {0,};따라서 배열 내의 모든 정수가 0으로 초기화됩니다.


최근 GNU C 레퍼런스 매뉴얼에서 다음과 같은 내용을 읽었습니다.

구조 변수를 초기화하지 않으면 정적 저장소가 있는지 여부에 따라 영향이 달라집니다(스토리지 클래스 지정자 참조).이 경우 정수형 멤버는 0으로 초기화되고 포인터 멤버는 NULL로 초기화됩니다.그렇지 않으면 구조 멤버의 값은 부정됩니다.


부분 자동구조와 자동배열 초기화에 대해 C와 C++ 규격에 대해 알려주시겠습니까?위의 코드는 Visual Studio에서 문제없이 실행하지만 gcc/g++ 및 다른 컴파일러와 호환성을 원합니다.고마워요.

링크된 gcc 문서에서는 부분 초기화에 대해서는 언급하지 않고 (완료)만 언급하고 있습니다.초기화 또는 초기화 없음.

부분 초기화란 무엇입니까?

표준에서는 개체의 부분 초기화를 정의하지 않습니다.완료 초기화 또는 초기화 없음 중 하나가 있습니다.Partial Initialization(부분 초기화)은 비표준 용어이며, 일반적으로 일부 이니셜라이저를 제공하지만 일부 이니셜라이저를 제공하지는 않습니다.즉, 초기화되는 어레이 크기 또는 구조 요소의 수보다 적은 이니셜라이저를 의미합니다.

예제:

int array[10] = {1,2};                    //Case 1:Partial Initialization

개요 (완전)초기화 또는 초기화 없음

초기화란 변수가 생성될 때 동시에 생성되는 변수에 일부 초기값을 제공하는 것을 의미합니다.즉, 같은 코드스테이트먼트에 있습니다.

예제:

int array[10] = {0,1,2,3,4,5,6,7,8,9};    //Case 2:Complete Initialization
int array[10];                            //Case 3:No Initialization

인용된 단락은 다음 동작에 대해 설명합니다.Case 3.

부분 초기화에 관한 규칙(Case 1)는 표준에서 잘 정의되어 있으며 이러한 규칙은 초기화할 변수의 스토리지 유형에 의존하지 않습니다.
AFAIK, 모든 메인스트림 컴파일러는 이러한 규칙을 100% 준수합니다.


부분 자동구조와 자동배열 초기화에 대해 C와 C++ 규격에 대해 알려주시겠습니까?

C 및 C++ 규격에서는 정수 배열이 자동 스토리지에 배치되어 있고 괄호 안에 있는 이니셜라이저가 적은 경우에도 초기화되지 않은 요소는 다음과 같이 초기화해야 합니다.0.

C99 표준 6.7.8.21

괄호로 둘러싸인 리스트 내의 이니셜라이저가 애그리게이트의 요소 또는 멤버의 수보다 적은 경우 또는 기존의 크기의 배열을 초기화하기 위해 사용되는 문자열 리터럴 내의 문자 수가 어레이 내의 요소 수보다 적은 경우 애그리게이트의 나머지 문자는 정적 저장 기간을 갖는 객체와 암묵적으로 동일하게 초기화되어야 한다.


C++에서는 규칙이 약간 다르게 기술되어 있습니다.

C++03 Standard 8.5.1 집약
패러그래프 7:

목록에 집약 멤버보다 이니셜라이저가 적은 경우 명시적으로 초기화되지 않은 각 멤버는 값 초기화됩니다(8.5). [예:

 struct S { int a; char* b; int c; };
 S ss = { 1, "asdf" };

초기화ss.a와 함께1,ss.b와 함께"asdf",그리고.ss.c그 형식의 표현의 가치를 가지고int(),그것은,0. ]

에 값 초기화가 정의되어 있는 동안
C++03 8.5 이니셜라이저
패러그래프 5:

타입 T의 오브젝트를 값 초기화 하는 것은 다음을 의미합니다.
: T가 사용자가 선언한 컨스트럭터(12.1)를 가진 클래스 타입(clause 9)인 경우 T의 디폴트컨스트럭터가 호출됩니다(T에 액세스 가능한 디폴트컨스트럭터가 없는 경우 초기화는 잘못된 형식입니다).
: T가 사용자가 선언한 컨스트럭터가 없는 비유니온 클래스 타입인 경우 T의 모든 비유니온 데이터 멤버 및 베이스 클래스 컴포넌트는 값이 초기화됩니다.
T가 어레이 타입인 경우 각 요소는 값이 초기화됩니다.
--그렇지 않으면 오브젝트는 제로 초기화됩니다.

C에서는 오브젝트가 부분적으로 초기화되지 않습니다.개체의 일부가 초기화되면 전체 오브젝트(및 모든 서브 오브젝트)가 재귀적으로 초기화됩니다.명시적 이니셜라이저가 제공되지 않는 경우 요소는 "해당 유형의 0"으로 초기화됩니다.

질문의 인용문은 하위 개체에 이니셜라이저가 없는 것이 아니라 전체 개체의 이니셜라이저가 완전히 생략된 경우를 말합니다.예를 들어, 다음과 같이 가정합니다.arr에는 자동 저장 기간이 있습니다.그 후, 다음과 같습니다.

int arr[100] = { 123 };

「」를 합니다.arr[0]로로 합니다.123 .arr로로 합니다.0 이것은 : 、 、 것 . 。

int arr[100];

arr초기화되지 않았습니다.이 인용문이 언급되고 있는 것은 후자의 경우입니다.

최신 gcc 버전에서는 초기화 및 제로엠을 동시에 실행할 수도 있습니다.

typedef struct{
  int a,b,c;
}T;

T s = {0, .b=5};

과 같은 값이 .a=0, b=5, c=0

다른 컴파일러가 이를 허용하는지 여부에 대한 정보는 없습니다.p

언급URL : https://stackoverflow.com/questions/10828294/c-and-c-partial-initialization-of-automatic-structure

반응형