Programing

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

lottogame 2020. 11. 18. 08:20
반응형

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


예를 들어 somestruct정수 멤버가 3 개인 경우 C (또는 C ++) 함수에서이 작업을 수행해도 좋다고 항상 생각했습니다.

somestruct s = {123,};

첫 번째 멤버는 123으로 초기화되고 마지막 두 멤버는 0으로 초기화됩니다. 저는 종종 자동 배열로 동일한 작업을 수행하여 배열의 int arr[100] = {0,};모든 정수가 0으로 초기화되도록 작성합니다.


최근에 GNU C Reference Manual 에서 다음과 같은 내용을 읽었습니다 .

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


누군가 부분 자동 구조 및 자동 배열 초기화와 관련하여 C 및 C ++ 표준이 말하는 것을 말해 줄 수 있습니까? 위의 코드를 Visual Studio에서 문제없이 수행하지만 gcc / g ++ 및 다른 컴파일러와 호환되기를 원합니다. 감사


링크 된 gcc 문서는 부분 초기화에 대해 이야기하지 않고 단지 (Complete) Initialization 또는 No 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 Aggregates
Para 7 :

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

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

초기화 ss.a1, ss.b"asdf",와 ss.c형태의 식의 값에 int(),이다 0. ]

Value Initialization은
C ++ 03 8.5 Initializers Para 5 :에 정의되어 있습니다
.

T 유형의 객체 값 초기화 한다는 것은 다음을 의미합니다.
— T가 사용자가 선언 한 생성자 (12.1)가있는 클래스 유형 (절 9)이면 T에 대한 기본 생성자가 호출됩니다 (T 인 경우 초기화 형식이 잘못됨). 액세스 가능한 기본 생성자가 없습니다.
— T가 사용자 선언 생성자가없는 비 유니온 클래스 유형이면 T의 모든 비 정적 데이터 멤버와 기본 클래스 구성 요소가 값으로 초기화됩니다.
— T가 배열 유형이면 각 요소는 값이 초기화됩니다.
— 그렇지 않으면 개체가 0으로 초기화됩니다.


C에서 객체는 부분적으로 초기화 되지 않습니다. 객체의 일부가 초기화되면 전체 객체 (및 모든 하위 객체)가 재귀 적으로 초기화됩니다. 명시적인 이니셜 라이저가 제공되지 않으면 요소는 "적절한 유형의 0"으로 초기화됩니다.

귀하의 질문에서 인용문은 하위 개체에 이니셜 라이저가 없을 때가 아니라 전체 개체의 이니셜 라이저가 완전히 생략 된 경우를 나타냅니다. 예를 들어 arr자동 저장 기간이 있다고 가정하면 다음과 같습니다.

int arr[100] = { 123 };

처음 상태 arr[0]123및 다른 모든 요소 arr0. 반면에 :

int arr[100];

모든 요소를 arr초기화되지 않은 상태로 둡니다 . 인용문이 언급 된 것은 후자의 경우입니다.


newest gcc versions also allow to "partially" initialize and zeromem at the same time:

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

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

the struct members now will have these values: a=0, b=5, c=0

i don't have any info on whether other compilers allow this or not :p


If the variable is global and static, it allocates in global area of binaries which is initialized to zero. If the variable is local, it allocates in stack, the compiler doesn't initialize the memory in stack.(some debug version may initialize, but release version never do it)

If the variable is allocated in Heap, the compiler doesn't initialize it either.


// You can use something like this:
typedef struct {

    ...;

    ...;

} somestruct;

// Declaration of struct
somestruct st;

// Initialising with 0. It does not depend on the size of the
// structure and the number of elements in it.
// memset() initialisation doesn't care if struct is static or dynamic.
// but don't forget to use st instead &st to dynamic.
memset(&st, 0, sizeof(somestruct));

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

반응형