C 함수 호출의 기본 인수 승격
세우다
C에서 함수를 호출할 때 기본 인수 프로모션에 대해 몇 가지 질문이 있습니다.다음은 C99 표준(pdf)의 6.5.2.2 "기능 호출" 항목 6, 7 및 8항입니다(읽기 쉽도록 목록에 추가 및 분할 강조).
제6항
- 호출된 함수를 나타내는 식이 프로토타입을 포함하지 않는 형식을 가질 경우, 각 인수에 대해 정수 승격이 수행되고, 다음과 같은 형식을 갖는 인수에 대해 정수 승격이 수행됩니다.
float
으로double
이를 기본 인수 승격이라고 합니다.- 인수의 수가 매개 변수의 수와 같지 않으면 동작이 정의되지 않습니다.
- 함수가 프로토타입을 포함하는 형식으로 정의되고 프로토타입이 생략 부호로 끝나는 경우(
, ...
후 이 매개되지 않았습니다.) 또는 승격 후 인수 유형이 매개 변수 유형과 호환되지 않으므로 동작이 정의되지 않았습니다.- 함수가 프로토타입을 포함하지 않는 형식으로 정의되고 승격 후 인수 유형이 승격 후 매개 변수의 인수 유형과 호환되지 않는 경우 다음 경우를 제외하고 동작이 정의되지 않습니다.
- 하나의 승격 유형은 부호 있는 정수 유형이고, 다른 승격 유형은 해당하는 부호 없는 정수 유형이며, 값은 두 유형 모두에서 표시됩니다.
- 또는 되지 않은 버전에 입니다.
void
.
제7항
- 호출된 함수를 나타내는 식에 프로토타입이 포함된 유형이 있는 경우, 할당된 것처럼 인수가 해당 매개변수의 유형으로 암시적으로 변환되어 선언된 유형의 정규화되지 않은 버전으로 각 매개변수의 유형을 취합니다.
- 함수 프로토타입 선언기의 생략 부호로 인해 마지막으로 선언된 매개 변수 뒤에 인수 형식 변환이 중지됩니다.기본 인수 승격은 후행 인수에 대해 수행됩니다.
제8항
- 다른 변환은 암묵적으로 수행되지 않습니다. 특히 인수의 수와 유형은 함수 프로토타입 선언자를 포함하지 않는 함수 정의의 매개 변수와 비교되지 않습니다.
내가 아는 것
- 기본 인수 승격은 다음과 같습니다.
char
그리고.short
int
/unsigned int
그리고.float
double
- 함수에 예: 변함예수수인선수적택대한에예▁to)
printf
에 해당합니다.
참고로, 함수 프로토타입에 대한 저의 이해는 다음과 같습니다.
void func(int a, char b, float c); // Function prototype
void func(int a, char b, float c) { /* ... */ } // Function definition
질문.
이 모든 것을 더듬느라 정말 힘들어요.몇 가지 질문이 있습니다.
- 기본 프로모션 및 암묵적 변환과 같이 프로토타입 기능과 비프로토타입 기능의 동작이 정말 많이 다릅니까?
- 기본 인수 승격은 언제 발생합니까?항상 그래요?아니면 (변수 함수와 같은) 특별한 경우에만 해당합니까?기능의 프로토타입 여부에 따라 달라집니까?
A 프로그래머의 대답을 지지했습니다. 그것들이 진짜 상품입니다.
상황이 왜 이러는지 궁금해하시는 분들을 위해: 1988년 이전의 암흑시대에는 고전적인 "K&R" C에 함수 원형과 같은 것이 없었고, (a) 레지스터에 단어를 넣는 것보다 바이트를 넣는 것이 비용이 더 들지 않기 때문에 본질적으로 "공짜"이 있었기 때문에 기본 주장 승격이 도입되었습니다.및 (b) 매개 변수 전달에서 발생할 수 있는 잠재적 오류를 줄입니다.그 두 번째 이유는 그것을 완전히 잘라내지 못했고, 이것이 ANSIC에 기능 프로토타입을 도입한 것이 C 언어에서 가장 중요한 단일 변화인 이유였습니다.
기본 승격이 시작되는 시기: 기본 인수 승격은 예상되는 인수 유형을 알 수 없을 때, 즉 프로토타입이 없거나 인수가 변수일 때 정확하게 사용됩니다.
프로토타입을 사용하는 함수에 대한 (비변량) 파라미터는 해당 유형(char, short, float)으로 변환됩니다.
프로토타입 및 변수 매개 변수가 없는 함수에 대한 매개 변수는 기본 인수 승격의 영향을 받습니다.
함수를 프로토타입으로 정의하고 프로토타입 없이 사용하거나 그 반대로 사용할 경우, char, short 또는 float 형식의 매개 변수가 있으면 런타임에 문제가 발생할 수 있습니다.승격된 유형이 인수 목록을 읽을 때 사용된 유형과 일치하지 않으면 변수 함수에 동일한 문제가 발생합니다.
예 1: 프로토타입을 사용하여 함수를 정의하고 사용하지 않을 때 문제가 발생합니다.
definition.c
void f(char c)
{
printf("%c", c);
}
use.c
void f();
int main()
{
f('x');
}
int가 전달되고 함수가 char를 예상하기 때문에 실패할 수 있습니다.
예 2: 프로토타입 없이 함수를 정의하고 사용할 때 문제가 발생합니다.
definition.c
void f(c)
char c;
{
printf("%c", c);
}
(이것은 일종의 정의로 매우 오래된 것입니다.)
use.c
void f(char c);
int main()
{
f('x');
}
int가 필요하지만 char가 전달되기 때문에 실패할 수 있습니다.
참고: 표준 라이브러리의 모든 기능에는 기본 승격에서 파생된 유형이 있습니다.따라서 프로토타입이 추가되었을 때 전환 과정에서 문제가 발생하지 않았습니다.
용어에 대한 약간의 오해가 원인입니다. 선언과 정의 모두 프로토타입을 포함할 수 있습니다(또는 포함하지 않을 수 있습니다).
void func(int a, char b, float c);
그것은 프로토타입을 포함하는 함수 선언입니다.
void func(int a, char b, float c) { /* ... */ }
이것은 프로토타입을 포함하는 함수 정의입니다.
"프로토타입"과 "비프로토타입"은 함수 유형의 속성일 뿐이며, 선언과 정의 모두 함수 유형을 소개합니다.
따라서 프로토타입 없이 선언을 할 수 있습니다.
void func();
또는 프로토타입 없이 정의할 수 있습니다(K&RC 스타일).
void func(a, b, c)
int a;
char b;
float c;
{ /* ... */ }
언급URL : https://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls
'programing' 카테고리의 다른 글
사용자 테이블에서 일치하는 행을 찾을 수 없습니다. (0) | 2023.07.25 |
---|---|
파워셸 언로드 모듈...완전히. (0) | 2023.07.25 |
SSH를 로그아웃한 후에도 백그라운드에서 스크립트를 실행하는 방법은 무엇입니까? (0) | 2023.07.20 |
UITableView에서 횡단 머리글의 기본 높이 (0) | 2023.07.20 |
c#에서 매개 변수화된 쿼리를 실행하는 동안 ORA-01745 오류가 발생했습니다. (0) | 2023.07.20 |