programing

C 함수 호출의 기본 인수 승격

i4 2023. 7. 25. 20:26
반응형

C 함수 호출의 기본 인수 승격

세우다

C에서 함수를 호출할 때 기본 인수 프로모션에 대해 몇 가지 질문이 있습니다.다음은 C99 표준(pdf)의 6.5.2.2 "기능 호출" 항목 6, 7 및 8항입니다(읽기 쉽도록 목록에 추가 및 분할 강조).

제6항

  1. 호출된 함수를 나타내는 식이 프로토타입을 포함하지 않는 형식을 가질 경우, 각 인수에 대해 정수 승격이 수행되고, 다음과 같은 형식을 갖는 인수에 대해 정수 승격이 수행됩니다.float으로 double이를 기본 인수 승격이라고 합니다.
  2. 인수의 수가 매개 변수의 수와 같지 않으면 동작이 정의되지 않습니다.
  3. 함수가 프로토타입을 포함하는 형식으로 정의되고 프로토타입이 생략 부호로 끝나는 경우(, ... 후 이 매개되지 않았습니다.) 또는 승격 후 인수 유형이 매개 변수 유형과 호환되지 않으므로 동작이 정의되지 않았습니다.
  4. 함수가 프로토타입을 포함하지 않는 형식으로 정의되고 승격 후 인수 유형이 승격 후 매개 변수의 인수 유형과 호환되지 않는 경우 다음 경우를 제외하고 동작이 정의되지 않습니다.
    • 하나의 승격 유형은 부호 있는 정수 유형이고, 다른 승격 유형은 해당하는 부호 없는 정수 유형이며, 값은 두 유형 모두에서 표시됩니다.
    • 또는 되지 않은 버전에 입니다.void.

제7항

  1. 호출된 함수를 나타내는 식에 프로토타입이 포함된 유형이 있는 경우, 할당된 것처럼 인수가 해당 매개변수의 유형으로 암시적으로 변환되어 선언된 유형의 정규화되지 않은 버전으로 각 매개변수의 유형을 취합니다.
  2. 함수 프로토타입 선언기의 생략 부호로 인해 마지막으로 선언된 매개 변수 뒤에 인수 형식 변환이 중지됩니다.기본 인수 승격은 후행 인수에 대해 수행됩니다.

제8항

  1. 다른 변환은 암묵적으로 수행되지 않습니다. 특히 인수의 수와 유형은 함수 프로토타입 선언자를 포함하지 않는 함수 정의의 매개 변수와 비교되지 않습니다.

내가 아는 것

  • 기본 인수 승격은 다음과 같습니다.char그리고.shortint/unsigned int그리고.floatdouble
  • 함수에 예: 변함예수수인선수적택대한에예▁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

반응형