[cfe-dev] Default argument type for function without prototype?

Csaba Raduly via cfe-dev cfe-dev at lists.llvm.org
Sun Jan 21 15:07:32 PST 2018


Hi Kirill,

On Sat, Jan 20, 2018 at 11:21 AM, Kirill Balunov via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
> Hi,
>
> I am a beginner to C and I previously asked this question on SO (and it was
> marked as duplicate :-) ) I still do not understand the problem to the end.

What is your question that is related to the development of the clang compiler?

> I understand the need of function prototypes and the default argument
> promotion machinery. But I am still confused with the obtained warning and
> final result for this example:
>
> #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].I can not understand why it is supposed by a
> compiler that val should be treated as int

Because the C standard says so. Read this StackOverflow answer:
https://stackoverflow.com/a/13950800

especially the part that says:  "If no variable type is in front of a
variable in the parameter list, then int is assumed"

When the compiler compiles the "impl" function, it has to assign a
type to the variable "val". The standard says this type has to be
"int". The compiler can't take into account that in main() you're
passing a double to "impl".

> and not to skip the number and
> types of arguments and then perform default argument promotion at run time.
> Also I read that if you don't provide argument types in ANSI C:
>>
>> 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 should 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.


You wrote "void impl();". This told the compiler not to check the type
of arguments passed to the "impl" function.

Later you wrote "impl(3.0)". The compiler dutifully passed the double
value to the impl function: it loaded the value into the xmm0
register, because the x86-64 calling convention passes the first few
arguments in registers.
(line 7 in https://godbolt.org/g/puW5b1)

Later you wrote "void impl(var)" and called printf. The compiler
passed the string "%.2f" to the printf function as the first argument
(lines 19 and 22), then it passed the integer it received in the rdi
register as the second argument to printf (lines 20 and 21). It also
passed the number of floating point arguments in vector registers
passed to printf  in the al register (zero, line 23).

impl expected an int argument in the rdi register. Unfortunately,
because you called impl with a double, the value of rdi contained
garbage. This got passed to printf. I have no idea what printf did
when instructed to print a double (with "%f") and then it was told
that no floating-point values were given to it.

>
> So I'm still confused what is happening here. Also I can't find where it is
> stated that the argument without a type should be treated by a compiler as
> type int.

See the StackOverflow answer.

> I understand that the question is stupid in nature, for this I
> apologize in advance, but it somehow sat down in my head and I nowhere can I
> find why it happens. Thank you!
>
> p.s.: Compiled with clang 6.0 and --std=c89 flag under Windows 10. Apologies
> if this question is off-topic for this list, but i can't find any other.

I don't understand this. A google search for "mailing list" returns
almost eight million results. You could have sent your question to any
of them.

Csaba
-- 
GCS a+ e++ d- C++ ULS$ L+$ !E- W++ P+++$ w++$ tv+ b++ DI D++ 5++
The Tao of math: The numbers you can count are not the real numbers.
Life is complex, with real and imaginary parts.
"Ok, it boots. Which means it must be bug-free and perfect. " -- Linus Torvalds
"People disagree with me. I just ignore them." -- Linus Torvalds



More information about the cfe-dev mailing list