sqrt() - Why am I allowed to provide an argument of int and not only double and the output is also right?
Asked Answered
K

1

4

I wondering why the compiler let this pass and is giving the right output, although sqrt() from its prototype normally should only get an double value as argument:

In C99 the declaration of the prototype is:

double sqrt (double x);

#include <stdio.h>
#include <math.h>

int main (void)
{  
   int i = 9;

   printf("\t Number \t\t Square Root of Number\n\n");

   printf("\t %d \t\t\t %f \n",i, sqrt(i)); 

}

Output:

 Number      Square Root of Number

 9           3.000000 

Why does the compiler not throw a warning at least and the given output is right, if I´m giving the sqrt() function an int as argument?

Is this crossing into Undefined Behavior?

I´m using gcc.


The Question was already asked twice for C++, but not for C, so my question is up for C. I provide the links to the questions for C++ anyway:

Why does sqrt() work fine on an int variable if it is not defined for an int?

Why is sqrt() working with int argument?

Karleen answered 12/12, 2019 at 18:11 Comment(0)
E
7

This is not undefined behavior.

The function is defined to accept an argument of type double. Because the type of the argument is known, you can pass an int because it may be implicitly converted to a double. It's the same as if you did:

int i = 4;
double d = i;

The rules for conversion of function arguments are spelled out in section 6.5.2.2p7 of the C standard regarding the function call operator ():

If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments

In contrast, if you passed an int to printf when the format string expects a double, i.e.:

printf("%f\n", 4);

Then you have undefined behavior. This is because the types of the arguments are not known at compile time so the implicit conversion can't happen.

Edlun answered 12/12, 2019 at 18:15 Comment(2)
Thank you very much. And also my desired citation of the standard. Thank you very much for your efforts. I have one question more: Does this also work with a char? Like f.e. when i take your example: char c = 4; double d = c; or as in my given example: printf("\t %d \t\t\t %f \n",i, sqrt(c)); Or does that only applies to the conversion from int to double?Karleen
@RobertS-ReinstateMonica A char can be implicitly converted to a double as well. In addition, a char can be promoted to an int in places where an int can be used. This includes being an argument to printf, so you can pass a char value with a %d format specifier.Edlun

© 2022 - 2024 — McMap. All rights reserved.