[c] sizeof (my_arr) [0]이 컴파일되고 sizeof (my_arr [0])과 같은 이유는 무엇입니까?

이 코드는 왜 컴파일됩니까?

_Static uint32_t my_arr[2];
_Static_assert(sizeof(my_arr) == 8, "");
_Static_assert(sizeof(my_arr[0]) == 4, "");
_Static_assert(sizeof(my_arr)[0] == 4, "");

첫 번째 두 가지 주장은 분명히 정확하지만 내 이해는 sizeof()정수 리터럴로 평가해야하며 배열로 취급 할 수 없기 때문에 마지막 줄이 실패 할 것으로 예상했을 것 입니다. 즉, 다음 줄이 실패하는 것과 같은 방식으로 실패합니다.

_Static_assert(4[0] == 4, "");

흥미롭게도, 다음은 실제로 컴파일에 실패합니다 (같은 작업을 수행해야합니까?).

_Static_assert(*sizeof(my_arr) == 4, "");

오류 : 단항 ‘*’의 유효하지 않은 유형 인수 ( ‘long unsigned int’가 있음) _Static_assert (* sizeof (my_arr) == 4, “”);

중요한 경우 gcc 5.3.0을 사용하고 있습니다.



답변

sizeof기능이 아닙니다. !또는 과 같은 단항 연산자 ~입니다.

sizeof(my_arr)[0]로 파싱 sizeof (my_arr)[0]그냥, sizeof my_arr[0]중복 괄호.

이것은로 !(my_arr)[0]구문 분석하는 것과 같습니다 !(my_arr[0]).

C. 안으로 일반적 후위 연산자 프리픽스 사업자보다 높은 우선 순위를 가질 sizeof *a[i]++로 파싱 sizeof (*((a[i])++))(후위 연산자 []++인가되는 a제 다음 프리픽스 연산자 *sizeof ).

(이것은 표현 버전입니다 sizeof. 괄호로 묶인 유형 이름을 취하는 유형 버전도 있습니다.이 sizeof (TYPE)경우 sizeof구문 이 필요하고 구문의 일부가 됩니다.)


답변

sizeof두 개의 “버전”이 있습니다 : sizeof(type name)sizeof expression. 전자 ()는 논쟁의 여지 가 필요하다 . 그러나 후자는 식으로 주장하는 식으로 논쟁의 여지가 없다 (). ()인수에 사용하는 것이 무엇이든 인수 표현식의 일부로 간주됩니다.sizeof 구문 자체.

my_arr컴파일러에 유형 이름이 아닌 객체 이름으로 알려져 있기 때문에sizeof(my_arr)[0] 실제로는 컴파일러 sizeof가 표현식에 적용되는 것으로 간주됩니다 . sizeof (my_arr)[0]여기서 (my_arr)[0]인수 식은 어디 입니까? ()주변 배열 이름 순수 불필요하다. 전체 표현은로 해석됩니다 sizeof my_arr[0]. 이것은 이전과 같습니다 sizeof(my_arr[0]).

(이것은 BTW, 이전 버전 sizeof(my_arr[0])에도 불필요한 쌍이 포함되어 있음을 의미합니다 ().)

sizeof구문에는 어쨌든 ()논쟁 의 쌍이 필요 하다는 오해가 널리 퍼져 있습니다. 이러한 오해는 다음과 같은 표현을 해석 할 때 사람들의 직관을 오도하는 것입니다 sizeof(my_arr)[0].


답변

[]보다 우선 순위가 높습니다 sizeof. 그래서 sizeof(my_arr)[0]동일하다 sizeof((my_arr)[0]).

우선 순위 테이블에 대한 링크는 다음과 같습니다 .


답변

sizeof표현식을 매개 변수로 사용하는 연산자 버전을 사용하고 있습니다. 유형을 취하는 것과 달리 괄호 필요 하지 않습니다 . 따라서 피연산자는 간단 (my_arr)[0]하며 괄호는 중복됩니다.


답변