2013-08-30 19 views
2

다음 함수 선언 및 정의를 고려하십시오. 소스 파일에서Visual Studio의 C4028 경고 (선언과 다른 형식 매개 변수)가 가짜입니까?

void some_function(int param); 

: 헤더 파일에서

#include "test.h" 

void some_function(const int param) {} 

int main(void) { 
    return 0; 
} 

비주얼 스튜디오 2010에서, 순수 C 프로젝트로 컴파일, 나는 warning C4028: formal parameter 1 different from declaration를 참조하십시오. 그러나 내가 아는 한, 이것은 완벽하게 유효한 C이며 상당히 일반적인 관행입니다.

나는 이것에 관해 틀렸고, VS2010 따라서 나에게 경고하는 것이 맞습니까? 또는 위조 된 경고 인 경우 이러한 유형의 경우에 특별히 해제 할 수 있습니까? 그러나 일치하지 않는 매개 변수 유형의 실제 사례에 대한 경고는 계속 유지해야합니까?

(VS2010와 함께 제공되는 실제 컴파일러는 다음과 같습니다 마이크로 소프트 (R) 32 비트 C/C++ 최적화 컴파일러 버전 16.00.30319.01는 80X86에 대한 나의 명령 행은 단순히 cl test.c입니다..)

+0

흥미 롭습니다. "일반적인 관행"에서 이것을 어디에서 보았습니까? 그리고 네, 경고하는 것이 옳습니다.이 경우에는 값 매개 변수부터 핥아도 상관 없으며, 구현 측면에서 부팅하는 것이 더 중요합니다. * 포인터 *를 사용하면 큰 차이를 만들 수 있습니다. 예 : 구현시 * prototype * 및'char *'에있는'const char * '의 파생을 고려하십시오. – WhozCraig

+0

@WhozCraig - 포인터 매개 변수와 같은 것은'const char * param'이 아니라'char * const param'이됩니다. – detly

+0

@WhozCraig -하지만 그래, 그건 중요하지 않다는 것을 안다. 그것이 내 요점이다. 이것은 컴파일러와 개발자에게'param'은 함수 본문에 의해 변경 될 수 없다는 것을 알려주는데, 이는 선언에서 노출 될 필요가없는 구현 세부 사항입니다. 그렇다면 VS2010은 비 호환성, 동작의 차이 및 예기치 않은 동작의 가능성이 없을 때 경고를 발행하는 이유는 무엇입니까? – detly

답변

1

C89 3.5.4.3 Function declarators가있다 매개 변수에 대해 말하면 다음과 같습니다.

두 함수 유형이 호환 될 수 있으려면 둘 다 호환 가능한 반환 유형을 지정해야합니다. 또한 매개 변수 유형 목록이 둘 다 존재하는 경우 매개 변수 수와 줄임표 종결 자 사용에있어서 일치해야합니다. 해당 매개 변수에는 호환 가능한 유형이 있어야합니다.

섹션 3.1.2.6 Compatible type and composite type은 동일한 유형의 호환 가능한 유형을 지정합니다. 이 유형 예선 (이 중 const 하나입니다)와 그 상태에 대한 3.5.3 참조 :

이 개 자격을 갖춘 유형이 호환되도록하려면, 모두 호환되는 유형의 동일하게 자격을 갖춘 버전을 가져야한다; 지정자 또는 한정자 목록 내의 유형 한정자의 순서는 지정된 유형에 영향을주지 않습니다.

지금 당신은 일반적으로 intconst int하지 호환 유형이라는 것을 그러므로 고려할 것입니다. 그러나 나는 그 표준의 오판이라고 믿습니다. 왜냐하면 int은 자격을 갖춘 타입이 아니기 때문에 위의 인용문은 적용되지 않습니다. 자격을 갖춘 유형으로 선언 된 각 매개 변수에 대한

, 이러한 비교에 대한 형이 선언 된 유형의 규정되지 않은 버전입니다 :이

3.5.4.3에서 나중에 더 적용 인용 진술이입니다.

그러므로 intconst int은 유사하게 허용되어야합니다. 은 표준에 따라 오류가 없음을 의미합니다. 마이크로 소프트는 그들의 지혜로 의심스러운 행동이며 경고를 유발할 좋은 이유라고 생각할 수도 있습니다.

문제가 있다고 생각하더라도 Microsoft에서 해결할 가능성은 매우 낮습니다 (아래 참조). 내가 C89을 인용하고있어 이유를 사용할 수 훨씬 더 현대적인 기준이있을 때


이제 당신은 궁금 할 수 있습니다.

Microsoft는 here에 따라, 비주얼 C++에서 주로 C++ 컴파일러입니다 만 표준의 이전 itertions에 C 코드를 컴파일 할 수있는 비밀을하지 않습니다 때문이다 : 우리를 보낼 수있는 시간을내어

감사합니다 당신의 제안. 현재 VS2010에는 C99 지원을 구현할 계획이 없습니다. 이 제품주기를 마친 후에는 향후 계획을 위해 모든 제안을 검토 할 것입니다. - Mark Roberts, Microsoft. wikipedia page에서

그리고, :

허브 셔터에 따르면, C 컴파일러은 "역사적인 이유"에 포함되어 더욱 발전 할 계획되지 않습니다. 사용자는 유효한 C++ 인 C 언어의 하위 집합 만 사용하고 C++ 컴파일러를 사용하여 코드를 컴파일하거나 대신 Intel C++ 컴파일러 또는 GNU 컴파일러 모음과 같은 다른 컴파일러를 사용하는 것이 좋습니다. 우리는 C90 또는 ISO C++ 중의 일부가 아닌 ISO의 C 기능을 지원하지 않을 계획

:

이는 허브 셔터의 자신의 블로그, 관련 기사 here에서 확인할 수있다.

+0

어쨌든 저는 C89 만 신경 쓰고 있습니다. 사용할 수있는 현대 표준이 더 있을지 모르지만 사용할 수는 없습니다. – detly

+0

그래도 좋은 답변. 3.1.2.6이 다소 당혹 스럽다는 것을 알았습니다. – detly