2009-01-22 4 views
14

이 경고 사항은 걱정할 필요가 있습니까? 나는 이상한 행동을 일으킬 수 있다고 읽었습니다.경고 C4099 : '구조체'(MS VS 2k8)를 사용하여 '클래스'를 사용하여 처음 본 유형 이름

내가 컴파일하려고하는 예입니다. 누군가가 클래스로 개체를 선언하지만 구조에 typedef가있는 이유를 설명 할 수 있습니까? 클래스가 POD 인 경우 완벽하게 정상입니까?

감사합니다.

답변

23

이 경고는 한 유형 선언이 다른 유형 선언 ("클래스", 다른 하나는 "구조"라고 말함)을 가지고있을 때 나타납니다. 하나의 정의 규칙이 주어지면, 하나 이상의 정의를 제외한 모든 선언은 전달 선언이어야합니다. 경고는 일반적으로 유형의 전방 선언이 잘못되었음을 나타내며 대개 단순한 오타이므로 수정해야합니다. 이 경우에는 부작용이 없어야하지만 실제로 수정해야합니다.

그러나 이름 충돌이 발생하면 매우 불쾌한 일이 발생할 수 있습니다 ("네임 스페이스 사용"또는 글로벌 네임 스페이스 오염 사용). 이 경고는 두 개의 서로 다른 라이브러리의 헤더를 혼합하고 유형 이름이 충돌 함을 나타낼 수 있습니다. 이러한 조건 하에서 컴파일 된 코드는 예상치 못한 일을 할 수 있습니다.

내 충고 - 경고가 표시된 이유를 이해하고 수정하십시오. 경고가 타사 제품에있는 경우이를 수정하도록하십시오.

+0

큰 충고, 고마워. –

+2

http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling#Data_Type의 MS Mangling Scheme : 'union'은 'T'로, 'struct'는 'U'로, 'class'는 'V'로 인코딩됩니다. . –

+0

고마워요! , typedef 구조체를 찾을 수 있습니다. – HadesDX

1

이것은 나쁜 관행으로 간주되지만 기본적으로 동일한 데이터 유형이므로 클래스 정의와 구조체 선언을 혼합해도 문제가 없어야합니다. 가장 큰 차이점은 구조체 멤버는 기본적으로 public이기 때문에 클래스 멤버는 private이지만 그렇지 않으면 메모리 레이아웃이 동일하다는 것입니다.

+1

다른 이름 변환 알고리즘을 사용하는 컴파일러에서 좋지 않을 수 있습니다. – MSalters

0

클래스와 구조체의 차이는 클래스의 멤버와 함수는 기본적으로 private이며 구조체는 기본적으로 public입니다. 그래서 수업이 POD라는 사실은 여기서 차이를 만들어서는 안됩니다.
이 경고는 코드 유지 관리 (정의는 어딘가에 있지만 다른 곳에서는 업데이트되지 않음)에서 가져온 것이며 경고가 사라지도록 코드를 수정합니다 (예 : typedef의 클래스 사용).

4

위의 this에 대한 MSalters의 의견을 최상위로 가져 오면됩니다. 저는 VC의 결과로 '클래스'또는 '구조체'키워드를 사용하여 링커 오류를 찾기가 어려웠습니다.

문제가되지 않는다면 몇 시간 동안 머리를 긁을 수 있습니다!

1

Richard Corden이 정확합니다. MS에이 경고가 표시되는 이유가 있습니다. 데코 레이팅 된 (맹 글링 된) 이름은 유형 이름이 어떤 클래스 키 (구조체 또는 클래스)인지 포함합니다. 잘못된 클래스 키가 표시 될 때 어떤 객체를 인수로 사용하거나 해당 객체를 반환하는 함수 나 메소드가 참조되면 컴파일 오류가 발생하지 않지만 데코 레이팅 된 이름이 다르기 때문에 링커에서 불만을 제기합니다. 링커 오류는 찾고있는 기호 만 표시하므로 클래스 키가 일치하지 않는 것을 간과하기 쉽기 때문에 이전의보다 자세한 컴파일러 경고가 중요합니다. 물론 두 버전이 동일한 편집 단위에 나타나지 않을 수도 있습니다. 유일한 차이점은 기본 멤버 가시성이라고 생각하면 잠시 머리를 긁적 거리는 것입니다.

+0

더 새로운 MSVC 컴파일러에서 여전히 그렇습니까? 아니면'class'와'struct'가 현재 이름 맹 글링과 정말로 동일합니까? –

2

내 블로그 게시물에 "Is C4099 really a sillywarning?""이라는 제목으로이 경고문을 자세히 설명합니다. 내 결론은 가장 좋은 방법입니다. :-) 글쎄, 적어도 나를 위해서.

1

이 경고가 발생할 수있는 한 가지 사실은 프로젝트에서 참조와 동일한 DLL을 사용하면서 DLL에서 .tlb 파일을 가져 오기 위해 # 시도하는 것입니다. 난 그냥 내 프로젝트 내에서 참조로 DLL을 제거 하여이 문제를 해결.