2012-01-22 3 views
7

C 표준에 따르면 함수 정의의 경우 선언자에 식별자 목록이 포함되어있는 경우 의 경우 매개 변수 유형이 다음 선언 목록에 선언됩니다. 분명히 차이가 있습니다. 여기 선언자 외부의 매개 변수 선언

extern int max(int a, int b) 
{ 
return a > b ? a : b; 
} 

extern int max(a, b) 
int a, b; 
{ 
return a > b ? a : b; 
} 

는 A, B에서 INT; 매개 변수에 대한 선언 목록입니다. 이 두 정의의 차이는 이고 첫 번째 형식은 을 프로토 타입 선언으로 사용하므로 두 번째 형식은 함수에 대한 후속 호출 인 의 인수를 강제로 변환합니다.

프로그래머에게 이것은 무엇을 의미하며 컴파일러가 생성하는 코드에 영향을 줍니까?

답변

11

두 번째 경우에는 제공되는 인수가 올바른 유형인지 확인하는 것이 호출자의 책임입니다. 암시 적 변환은 제공되지 않습니다 (기본 인수 프로모션 제외). 섹션 6.5.2.2에서 :

호출 된 함수를 의미 표현이 프로토 타입을 포함하지 않는 유형이있는 경우

는 정수 프로모션은 각 인수에서 수행됩니다.

... 호출 된 함수를 나타냅니다 식 프로토 타입을 포함 않는 유형이있는 경우

는, 인수는 암시 적으로 변환됩니다 할당했을 경우 등의 해당 매개 변수의 유형.

따라서이 같은 호출 코드가 확인 될 것입니다 :

char x = 3; 
char y = 7; 
max(x, y); // Equivalent to max((int)x, (int)y) 

때문에 xy는 스택에 배치되기 전에 int으로 승격된다.

그러나이 같은 코드는 확인되지 않습니다 :

double x = 3.0; 
long y = 7; 
max(x, y); // Uh-oh 

xydoublelong로 스택에 배치되지만, max()는 정의 될 것이다,이 개 int의 읽기를 시도합니다 동작 (실제 비트는 재 해석 될 것입니다).

두 번째 양식을 사용하지 않는 이유 중 하나입니다. 표준에있는 유일한 이유는 레거시 코드와의 역 호환성을 제공하기 위해서입니다. GCC를 사용하는 경우 -Wold-style-definition 플래그를 사용하여이를 시행 할 수 있습니다. 나는 다른 컴파일러가 비슷한 것을 제공하기를 희망한다.