array [100] = {0}은 어떻게 전체 배열을 0으로 설정합니까?


140

컴파일러는 어떻게 값을 채우 char array[100] = {0};나요? 그 뒤에 마법은 무엇입니까?

내부적으로 컴파일러가 초기화되는 방법을 알고 싶었습니다.


1
C 또는 C ++에서? 그들은 두 가지 별도의 질문입니다.
Toby Speight

답변:


163

마법이 아닙니다.

C에서이 코드의 동작은 C 스펙의 6.7.8.21 섹션 ( C spec의 온라인 초안)에 설명되어 있습니다. 지정된 값이없는 요소의 경우 컴파일러는 NULL에 대한 포인터를 초기화하고 산술 유형은 0 ( 재귀 적으로 이것을 집계에 적용합니다).

C ++에서이 코드의 동작은 C ++ 사양의 8.5.1.7 ( C ++ spec 온라인 초안) 섹션에 설명되어 있습니다 . 컴파일러는 지정된 값이없는 요소를 집계 초기화합니다.

또한 C ++ (C는 아님)에서 빈 초기화 목록을 사용하여 컴파일러가 배열의 모든 요소를 ​​집계 초기화 할 수 있습니다.

char array[100] = {};

이 작업을 수행 할 때 컴파일러가 생성 할 수있는 코드 종류에 대해서는 다음 질문을 살펴보십시오. 배열 0 초기화의 이상한 어셈블리


모든 C 컴파일러가 이것을 수행합니까? Visual Studio만이 그렇게한다고 믿었습니다.
JFA

1
C ++ 사양의 온라인 초안이 깨졌습니다. 누구든지 새로운 링크가 있습니까?
Behrooz Karjoo

35

구현은 컴파일러 개발자에게 달려 있습니다.

귀하의 질문이 "그러한 선언으로 발생할 일"인 경우-컴파일러는 첫 번째 배열 요소를 제공 한 값 (0)으로 설정하고 다른 배열 요소는 생략 된 배열 요소의 기본값이므로 0으로 설정됩니다.


소스가 없지만 배열 선언에 대한 기본값이없는 곳을 읽었을 것입니다. 당신은 이미 쓰레기가 있던 것을 얻습니다. 어쨌든 덮어 쓸 가능성이있을 때이 값을 설정하는 데 시간을 낭비하는 것은 의미가 없습니다.
Ryan Fox

10
Ryan, 전체 배열이 초기화되지 않은 첫 번째 요소에 값을 설정하지 않고 실제로 가비지가 포함되어 있지만 적어도 하나의 요소에 대한 값을 설정하면 전체 배열이 초기화되어 지정되지 않은 요소가 암시 적으로 초기화됩니다. 0.
qrdl

1
C ++의 경우 경계 배열의 빈 초기화 목록은 모든 요소를 ​​기본값으로 초기화합니다.
dalle

2
@NatanYellin 이것이 정의되지 않았다고 어디에서 말했습니까? 의견을 제시하고 투표를하기 전에 전체 답변을 읽으십시오.
qrdl

1
@qrdl 당신이 맞아요. 구현에 대한 귀하의 의견을 오해했습니다. 안타깝게도 지금 투표를 변경할 수 없습니다.
Natan Yellin

27

컴파일러가 GCC 인 경우 다음 구문을 사용할 수도 있습니다.

int array[256] = {[0 ... 255] = 0};

http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits참조 하십시오. 이는 컴파일러 관련 기능입니다.


어서 오십시오! 당신이 그런 종류의 트릭을 더 많이 찾으라고 요청한 이후로, 나는 제공했습니다
lakshmanaraj

1
선택하면 확실히 할 수 있지만 이와 같은 컴파일러 관련 확장에 의존하는 것은 명백한 단점이 있습니다.
Dan Olson

@ Dan Olson 그의 질문은 컴파일러에 대해 묻는 것이므로 게시했습니다. 쓸모가 없다고 생각되면 삭제하겠습니다.
lakshmanaraj

5
쓸모없고 흥미 롭습니다. 경고는 주목할 가치가 있습니다.
Dan Olson

2
이런 식으로 나를 다시 돌아와서 몇 가지 최고의 답변보다 더 많이 읽습니다 ...
timday

19

이 초기화 위치에 따라 다릅니다.

배열이 다음과 같이 정적이면

char array[100] = {0};

int main(void)
{
...
}

그런 다음 프로그램의 데이터 분리에서 100 0 바이트를 예약하는 것은 컴파일러입니다. 이 경우 이니셜 라이저를 생략했을 수 있습니다.

배열이 자동이라면 또 다른 이야기입니다.

int foo(void)
{
char array[100] = {0};
...
}

이 경우 foo 함수를 호출 할 때마다 숨겨진 memset이 생깁니다.

위의 코드는

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

이니셜 라이저를 생략하면 배열에 임의의 데이터 (스택의 데이터)가 포함됩니다.

로컬 배열이 다음과 같이 정적으로 선언 된 경우

int foo(void)
{ 
static char array[100] = {0};
...
}

기술적으로 첫 번째와 같은 경우입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.