0

EDIT: Actually this is a duplicate for this question - Why does a function with no parameters (compared to the actual function definition) compile?

I am a beginner to C and while I understand the need of function prototypes and the default argument promotion machinery. I also read several posts about this topic on SO.

  1. Default argument promotions in C function calls
  2. C prototype functions

I am still confused with the obtained warning and final result for this simplified snippet.

#include <stdio.h>

void impl();

int main(void)
{   
    impl(3.0);
    return 0;
}

void impl(val)
{
    printf("%.2f", val);
}

I get the following warning: format specifies type 'double' but the argument has type 'int' [-Wformat] for this line printf("%.2f", val);

I can not understand why it is supposed by a compiler that val should be treated as int and not to perform default argument promotion. Also I read that if you don't provide argument types:

An ANSI C compiler will assume that you have decided to forego function prototyping, and it will not check arguments.

The result which is printed to the console is 0.00, but as I understood the caller will place double on the stack and %f also means double in printf so it reads double off the stack, and the result should not be affected. While this question C Function with parameter without type indicator still works? explains some bits, I still do not understand the problem to the end. Also I can't find where it is stated that the argument without a type should be treated by compiler as type int.

I think that I do not understand this part 6.5.2.2 "Function calls" written in the standard:

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.

Compiled with clang 6.0 and --std=c89 flag under Windows 10.

godaygo
  • 2,215
  • 2
  • 16
  • 33
  • 1
    You’ve declared `impl()` but it has no prototype. You define it using an implicit `int` argument. That was allowed in C90 (for backwards compatibility) but banned in c99. The other problems are consequences of these. – Jonathan Leffler Jan 17 '18 at 10:01
  • @JonathanLeffler yes I understand that I define a function with implicit argument, but I can not find the source where it is stated that implicit argument is treated as type `int`. Could you give me the link? – godaygo Jan 17 '18 at 14:06
  • This is stated in C89 standard in Section 3.7.1 under "Semantics" part. – godaygo Jan 22 '18 at 18:03

1 Answers1

1

This:

void impl(val)

doesn't specify the formal type of the val argument. This makes it default to int. This has nothing to do with what kind of value gets passed to the function at run-time, and would be equally true if the function was never called.

Also omitting the type is very old-school and not supported in modern C, I think.

unwind
  • 391,730
  • 64
  • 469
  • 606