sqrt() - 为什么我可以提供一个 int 参数,而不仅仅是 double 并且输出也是正确的?
sqrt() - Why am I allowed to provide an argument of int and not only double and the output is also right?
我想知道为什么编译器让这个通过并给出正确的输出,虽然 sqrt()
从它的原型通常应该只得到一个 double
值作为参数:
在 C99 中,原型的声明是:
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));
}
输出:
Number Square Root of Number
9 3.000000
如果我给 sqrt()
函数一个 int
作为参数,为什么编译器至少不发出警告并且给定的输出是正确的?
这是进入未定义行为吗?
我正在使用 gcc。
这个问题已经针对 C++ 提出过两次,但没有针对 C,所以我的问题是针对 C。
无论如何,我提供了 C++ 问题的链接:
Why does sqrt() work fine on an int variable if it is not defined for an int?
Why is sqrt() working with int argument?
这不是未定义的行为。
函数被定义为接受 double
类型的参数。因为参数的类型是已知的,所以您可以传递 int
,因为它可能会隐式转换为 double
。就像你做的一样:
int i = 4;
double d = i;
关于函数调用运算符 ()
:
的 C standard 第 6.5.2.2p7 节详细说明了函数参数转换的规则
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
相比之下,如果您将 int
传递给 printf
而格式字符串需要 double
,即:
printf("%f\n", 4);
那么你有未定义的行为。这是因为参数的类型在编译时是未知的,所以隐式转换不会发生。
我想知道为什么编译器让这个通过并给出正确的输出,虽然 sqrt()
从它的原型通常应该只得到一个 double
值作为参数:
在 C99 中,原型的声明是:
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));
}
输出:
Number Square Root of Number
9 3.000000
如果我给 sqrt()
函数一个 int
作为参数,为什么编译器至少不发出警告并且给定的输出是正确的?
这是进入未定义行为吗?
我正在使用 gcc。
这个问题已经针对 C++ 提出过两次,但没有针对 C,所以我的问题是针对 C。 无论如何,我提供了 C++ 问题的链接:
Why does sqrt() work fine on an int variable if it is not defined for an int?
Why is sqrt() working with int argument?
这不是未定义的行为。
函数被定义为接受 double
类型的参数。因为参数的类型是已知的,所以您可以传递 int
,因为它可能会隐式转换为 double
。就像你做的一样:
int i = 4;
double d = i;
关于函数调用运算符 ()
:
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
相比之下,如果您将 int
传递给 printf
而格式字符串需要 double
,即:
printf("%f\n", 4);
那么你有未定义的行为。这是因为参数的类型在编译时是未知的,所以隐式转换不会发生。