이 코드는 왜 컴파일됩니까?
_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]
하며 괄호는 중복됩니다.