没有无类型参数的调用方法 [英] Calling method without typeless argument

查看:71
本文介绍了没有无类型参数的调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到我不太了解C中的某些行为.如果我定义的函数没有为参数指定类型,并且不带任何参数调用它,则代码会编译,但会发出警告,指出参数的类型默认为 int .

I have noticed some behavior in C that I do not quite understand. If I define a function with an argument that I do not specify a type for and call it without any argument, the code compiles but gives a warning that the type of the parameter defaults to int.

void f(i) {
    printf("%d", i);
}
int main(void) {
    f();
}

如果我在godbolt上运行此,则会收到预期的编译器警告,并且执行将打印1到 stdout .

If I run this on godbolt, I get the expected compiler warning, and execution prints 1 to stdout.

但是,如果我定义相同的方法,但将参数显式声明为 int ,则编译器将为使用较少参数的函数调用引发错误.

However, if I define the same method, but explicitly declare the argument as an int, the compiler throws an error for the function being called with too few arguments.

void f(int i) {
    printf("%d", i);
}
int main(void) {
    f();
}

在Godbolt上编译会产生错误:函数'f'的参数太少.

此行为在gcc和clang的所有现代版本中都是一致的.为什么指定参数的类型会使它成为编译器错误?另外,是否定义了第一个示例的行为?gcc和clang总是使 i 1的事实使我认为这是故意的.如果是这样,为什么?

This behavior is consistent across all modern versions of gcc and clang. Why does specifying the type of the argument make this a compiler error? Also, is the behavior of the first example defined? The fact that gcc and clang both always make i 1 would make me think that this is intentional. If so, why?

推荐答案

第二段代码相对简单.该函数定义为接受一个参数,并且 main 中的函数调用未传递任何参数.这是一个明显的错误.

The second piece of code is relatively simple. The function is defined to accept one argument, and the function call in main passed no arguments. That's a clear error.

第一段代码更有趣.这可以追溯到旧式的函数定义,在该函数定义中,参数列表仅包含参数名称,并且类型出现在终止于参数列表的右括号和函数主体开始之前的右括号之间.正确定义的此类函数如下所示:

The first piece of code is more interesting. This goes back to old style function definitions where the parameter list contains only the names of the parameters and the types appear between the closing parenthesis terminating the argument list and the opening brace before the start of the function body. Such a function properly defined would look like this:

void f(i) 
  int i;
{
    printf("%d", i);
}

这种指定函数参数的样式可以追溯到原始的K& RC,但现在已被弃用.C的这种变体还具有以下属性:可以忽略变量的类型,在该变量中,其类型默认为 int .

This style of specifying function arguments dates back to the original K&R C but is considered deprecated now. This variant of C also had the property that the type of a variable could be omitted in which cast it defaults to int.

但是,即使您确实如上面的示例中那样在参数列表后指定了类型,它也是 still 而不是错误.那为什么呢?

However, even if you do specify the type after the argument list as in the above example, it's still not an error. So why is this?

关键部分来自

2 如果表示被调用函数的表达式的类型包含原型,则参数数应与参数数一致.每个参数应具有一种类型,以便可以将其值分配给具有对应参数类型的非限定版本的对象.

2 If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters. Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter.

...

8 不会隐式执行其他转换;尤其是,不将参数的数量和类型与不包含函数原型声明符的函数定义中的参数进行比较.

8 No other conversions are performed implicitly; in particular, the number and types of arguments are not compared with those of the parameters in a function definition that does not include a function prototype declarator.

以及有关功能定义的6.9.1p7节:

And section 6.9.1p7 regarding function definitions:

函数定义中的声明符指定要定义的函数的名称及其参数的标识符.如果声明符包括参数类型列表,则该列表还将指定所有参数的类型;否则,列表将指定所有参数的类型.这样的声明符还可以用作函数原型,以便以后在同一转换单元中调用同一函数.如果声明符包含标识符列表,则应在以下声明列表中声明参数的类型.在这两种情况下,每个参数的类型均按照6.7.6.3中关于参数类型列表的描述进行调整;结果类型应为完整的对象类型

The declarator in a function definition specifies the name of the function being defined and the identifiers of its parameters. If the declarator includes a parameter type list, the list also specifies the types of all the parameters; such a declarator also serves as a function prototype for later calls to the same function in the same translation unit. If the declarator includes an identifier list, the types of the parameters shall be declared in a following declaration list. In either case, the type of each parameter is adjusted as described in 6.7.6.3 for a parameter type list; the resulting type shall be a complete object type

在K& R样式函数定义的情况下,将参数指定为标识符列表,而不是参数类型列表.这意味着函数定义不会也指定函数原型,这意味着在调用函数时不会检查参数的数量和类型.

In the case of a K&R style function definition, the parameters are specified as an identifier list as opposed to a parameter type list. This means that the function definition does not also specify a function prototype, meaning the number and types of the parameters are not checked when the function is called.

这篇关于没有无类型参数的调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆