2013-04-05 2 views
7
typedef int A; 
typedef int B; 

void foo(A arg){} 

void main(void){ 
    B wrongvar = 7; 
    foo(wrongvar); 
} 

표준에 따라이 구조가 경고/오류를 반환 할 예정입니까? 가장 인기있는 컴파일러는 어떻습니까?'typedef'를 사용하여 논리적 유형 안전 보장

예 : 우리는 킬로그램과 미터를 나타내는 변수를 가지며 모두 'int'유형입니다. 우리는 미터를 처리하는 함수를 가지고 있습니다. 우리는 컴파일러가 변수 변수를 의미하는 킬로그램을 함수에 전달하는 것과 관련된 버그를 잡기를 원합니다.

나는 Ada이 원활하게 처리한다고 믿습니다. 현대 C는 어때?

+1

앞에'typedef' 이러한 문제를 방지 할 수있는 방법을 설명하는 새로운를 제공합니다 이름을 기존 유형으로; 새로운 유형을 생성하지 않습니다. 대체 이름은 동일한 유형을 참조합니다. 따라서'A','B','int','signed int'는 타입 위반없이'foo (A arg)'에 전달 될 수 있습니다. 유형도 경고를 이끌지 않고 전달할 수 있습니다. –

+0

'void main (void)'는'int main (void)'이어야하고'void main (void)'를 사용하라는 언급은 C를 잘 모르는 사람이 쓴 것입니다. –

+0

@KeithThompson, c99는'void main (void)'을 사용하는 것으로 보입니다 (http://stackoverflow.com/a/9356660/1145760). 오해는 질문에 올바르게 태그를 지정하지 않았기 때문입니다. – Vorac

답변

7

아니요, 다루는 것은 알려진 유형 문제입니다 구조적 동등성 대 이름 동등성. Dog가 말했듯이, 당신이 원하는 것을 성취하기 위해 할 수있는 가장 가까운 일은 구조체를 사용하는 것입니다. 그러나 컴파일러가 패딩을 추가하기를 원한다면 메모리 낭비가 될 수 있습니다 (이 경우는 없을 것입니다). C는 별칭에 대해 구조적 동등성 (두 유형이 같은 것을 의미 함)을 사용하지만 선언 된 다른 구조체에 대해 동일한 이름을 사용합니다 (동일한 레이아웃을 가진 두 가지 유형의 구조체는 동등한 것으로 처리되지 않습니다).

이 작업을 수행하는 구조체를 사용하는 예는 :

typedef struct { 
    double value; 
} meters; 

typedef struct { 
    double value; 
} kilograms; 

int main(){ 
    meters m; 
    kilograms k = {2}; // initialized 
    m.value = 1; 
    k = m; // error, can't assign meters to kilos 
    return 0; 
} 

이 문서 읽어하실 수 있습니다 : http://www.joelonsoftware.com/articles/Wrong.html 당신이 명명 규칙

+2

형식 이름의'_t' 접미사는 POSIX에 의해 예약됩니다. 유형은 변수와 별도의 네임 스페이스에 있으므로 어쨌든 구별되는 접미사를 사용할 이유가 없습니다. http://stackoverflow.com/a/231807/139746 –

+1

괜찮음, 제거됨 –

+0

이것은 언젠가 초보자가 와서 결과를 더 깊이 생각하지 않고'k.value = m.value; '라고 적기 때문에 반쪽 해결책 일뿐입니다 . 실제 안전을 원한다면 자신의 클래스를 정의해야합니다 (아마도 데이터 멤버로 int를 래핑하는 경우) 그리고 연산자를 허용해야합니다. –

2

하나의 필드가있는 구조체를 사용하여 원하는대로 정확하게 처리 할 수 ​​있습니다. 유일한 "단점"은 옵티마이 저가이를 최적화하지 않으면 1/2/4/8 바이트를 낭비한다는 것입니다 ...

+3

구조체의 크기는 멤버 변수의 크기와 모든 패딩 (필요한 경우)의 합계입니다. 멤버 변수 하나만있는 경우에는 공간 측면에서 오버 헤드가 없다고 생각합니다. –