2017-11-04 21 views
2

나는 C (리눅스) 코드 here 매크로의 다음과 같은 이상한 형태를 보았다?C 코드에서`((t *) 0) -> f)`무엇을합니까?</p> <pre><code>#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) </code></pre> <p><code>((t*)0)->f)</code>는 무엇입니까 :

어떻게 작동합니까?

+0

http://cdecl.org를 알고 계십니까? (비록이 문제에 대한 해결책이 아님) –

+1

C? '->'가 무엇인지 아십니까? – melpomene

+0

은 단지'sizeof'가't' 형 구조체의'f' 필드의 크기를 결정하도록합니다. – Serge

답변

4

이름에서 알 수 있듯이 구조체의 필드 크기를 전달합니다.

구조체 유형의 포인터에 0이 캐스트됩니다 (임의의 주소 임).

그런 다음 -> (포인터를 통한 액세스) 필드를 가져 와서 sizeof을 적용합니다.

매우 간단합니다!

+1

'0'은 임의적이지 않습니다. 그것은 널 포인터 상수이기 때문에'(t *) 0'는 널 포인터입니다. – melpomene

+1

'sizeof' 연산자가 사용 된 값을 평가하지 않는다면, 정의되지 않은 동작을 얻게 될 것입니다. 그것이 UB 인 경우조차 몇몇 논쟁의 문제는 ... – rodrigo

+0

@melpomeme. 포인터를 이름으로 지정해도이 컨텍스트에서는 덜 임의적이지 않습니다. 다른 어떤 값도 효과가있었습니다. 또한 NULL은 기술적으로 구현 종속적 인 값이며 반드시 0 일 필요는 없습니다. –

3

주석 위에서 말하는대로, Marcus Müller explains처럼합니다. 당신이 그것으로 귀찮게 왜 궁금해, 왜 우리는 단지 sizeof(type_of_field) 대신, 다음이 생각 할 수 없다 : 우리는 type_of_bar의 이름을 수 없습니다

struct foo { 
    struct { 
    int a; 
    float b; 
    } bar; 
}; 

, 프로그래머 것이 이름이없는 때문이다. 그러나 매크로를 사용하면 해결 방법을 통해 필드 크기를 얻을 수 있습니다.

2

sizeof는 컴파일 타임에 계산되므로 (여기서는 가변 길이 배열의 경우 제외) 해당 인수는 런타임에 계산되지 않습니다. 따라서 NULL 포인터를 캐스팅하는 것은 괜찮습니다. 크기가 계산되는 필드를 나타 내기 위해서만 사용되기 때문에입니다.

+0

이 중요한 정보입니다 충분히 언급되지 않았습니다. –