Default argument promotions in C function calls

前端 未结 3 462
小蘑菇
小蘑菇 2020-11-22 05:15

Setup

I have a few questions about the default argument promotions when calling a function in C. Here\'s section 6.5.2.2 \"Function calls\" Paragraphs 6, 7, and 8

相关标签:
3条回答
  • 2020-11-22 05:58

    Upvoted AProgrammer's answer—those are the real goods.

    For those of you who are wondering why things are this way: in the dark ages before 1988, there was no such thing as a function prototype in classic "K&R" C, and the default argument promotions were instituted because (a) there were essentially "free", as it costs no more to put a byte in a register than to put a word in a register, and (b) to cut down on potential errors in parameter passing. That second reason never quite cut it, which was why the introduction of function prototypes in ANSI C was the single most important change ever in the C language.

    As to when default promotions kick in: default argument promotions are used exactly when the expected type of the argument is unknown, which is to say when there's no prototype or when the argument is variadic.

    0 讨论(0)
  • 2020-11-22 06:08

    Your confusion stems from a very slight misunderstanding of the terminology - both declarations and definitions can include prototypes (or not):

    void func(int a, char b, float c);
    

    That is a function declaration that includes a prototype.

    void func(int a, char b, float c) { /* ... */ }
    

    That is a function definition that includes a prototype.

    "Prototyped" and "non-prototyped" are just attributes of a function type, and both declarations and definitions introduce the type of the function.

    So you can have a declaration without a prototype:

    void func();
    

    or you can have a definition without a prototype (K&R C style):

    void func(a, b, c)
        int a;
        char b;
        float c;
    { /* ... */ }
    
    0 讨论(0)
  • 2020-11-22 06:19
    • (Non variadic) parameters to functions with a prototype are converted to the corresponding type, which can be char, short, float.

    • Parameters to functions without prototype and variadic parameters are subject to default argument promotions.

    If you define a function with a prototype and use it without the prototype or vise versa and it has parameters of type char, short or float, you'll probably have a problem at run-time. You'll have the same kind of problems with variadic functions if the promoted type doesn't match what is used when reading the argument list.

    Example 1: problem when defining a function with a prototype and using it without.

    definition.c

    void f(char c)
    {
       printf("%c", c);
    }
    

    use.c

    void f();
    
    int main()
    {
       f('x');
    }
    

    can fail because an int will be passed and the function expect a char.

    Example 2: problem when defining a function without a prototype and using it with one.

    definition.c

    void f(c)
       char c;
    {
       printf("%c", c);
    }
    

    (This is kind of definition is very old fashioned)

    use.c

    void f(char c);
    
    int main()
    {
       f('x');
    }
    

    can fail because an int is expected but a char will be passed.

    Note: you'll remark that all functions from the standard library have types which result from default promotions. So they didn't cause problem during the transition when prototypes were added.

    0 讨论(0)
提交回复
热议问题