Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么这种声明函数的方式在C+中已经过时+;?_C++_C_Function_Syntax - Fatal编程技术网

C++ 为什么这种声明函数的方式在C+中已经过时+;?

C++ 为什么这种声明函数的方式在C+中已经过时+;?,c++,c,function,syntax,C++,C,Function,Syntax,这种类型的函数声明在C中有效,但为什么在C++中无效呢 int sum(i,j)int i,j; { return i+j; } 这些都是C的原始版本中使用的K&R样式原型。这些原型现在基本上被遗忘,并被ANSI原型所取代: int sum(int i, int j) 正如其他人所说,在函数声明中使用K&R原型是有问题的,因为它们不包含类型信息。假设编译器可以解析K& R函数定义,但不必编译任何编译器。 < P>我认为这是因为它降低了可读性,而且它没有被C++所接受的优势。 这种语法还使

这种类型的函数声明在
C
中有效,但为什么在
C++
中无效呢

int sum(i,j)int i,j;
{
  return i+j;
}

这些都是C的原始版本中使用的K&R样式原型。这些原型现在基本上被遗忘,并被ANSI原型所取代:

int sum(int i, int j)

正如其他人所说,在函数声明中使用K&R原型是有问题的,因为它们不包含类型信息。假设编译器可以解析K& R函数定义,但不必编译任何编译器。

< P>我认为这是因为它降低了可读性,而且它没有被C++所接受的优势。
这种语法还使接口声明复杂化。当K&R采用这种风格时,面向对象和基于接口的编程并不流行。

为什么它会有效?C++更喜欢类型安全。您也不应该在C中使用这种函数声明:它已经非常过时了。

实际上,它应该在任何地方都过时,因为它不像下面那样清晰:

int sum(int i, int j)
{
    return i+j;
}

…但我想它是从C++中丢失的,特别是因为它看起来非常像(并且可能会与)在构造函数中初始化的混淆:

void MyClass::MyClass():myVar(5)
{

}

这是因为老式的函数定义没有声明原型。也就是说,调用方不知道函数需要什么样的参数类型

在C++中,这是一种类型的安全缺失。FDIS特别表示

<> >强>更改:> C++,函数定义的语法排除了“旧式”C函数。在C语言中,允许使用“旧式”语法,但不推荐使用“过时”语法

理由:原型对类型安全至关重要

对原始特征的影响:删除语义上定义良好的特征

转换难度:语法转换

使用范围有多广:在旧程序中很常见,但已知已过时


出于好奇,你为什么要这样做/是什么引发了这个问题?FWIW,如果我们的代码评审中出现了这样的C代码,它会立即被拒绝。ISO可能觉得有必要保持向后兼容性,但没有人被迫允许在其漂亮的源代码中使用这种语法。要澄清的是,尽管大多数C编译器仍然接受这种语法,但它在C中也是过时的。要澄清的是,尽管它在C中已经过时,但它仍然在标准中。大多数编译器都接受它,因为大多数编译器都试图遵守标准。+1,我更喜欢这一个,因为它可以立即明确参数的类型。@cnicutar,由于参数列表很长,很难确定参数的类型。同样,你必须重复两次参数。@ cNICUTAR,因为C++代码解析已经复杂,并且C++ 11还添加了另一种函数声明格式。@ Alex B,@迭戈SeVale:这些都是人为原因。“Alex B,技术上,C++ 11只添加了一种定义参数后返回类型的方法。甚至这仅仅是因为解析器的需要。当然,您可以使结束参数后的声明符成为函数签名的一部分,相当于
sum(inti,intj)
,这样旧的C代码仍然可以接受,只要它指定结束参数后的类型?这不正是不赞成的理由吗?对我来说,它更像语法的统一和简化,如果我错了,请纠正我。你也可以允许Pascal代码与C++代码并列,但这并不意味着你应该。旧的C声明不起作用,所以它们被C++所忽略。@乔纳森,为什么,是的,你可以。在C++中,不允许K& R声明或内联PASCAL代码的技术原因,这意味着声明的旧样式的类型安全性不是答案中指出的不赞成的原因,不是吗?@ AlexB,不能完全完成这项工作。如果您尝试,下一个问题将是
void f();void g(){f(0);}/*随机C代码*/
。为了实现这一点,您需要再次向类型安全性说再见,并要求空参数列表使用
(void)
。这不是C++的。亚历克斯,我想表达的是,允许这样的定义是完全没有用的。目的是什么?大多数包含此类定义的C代码仍然无法编译,因为它们包含类似于我的注释中的调用。为什么不允许函数定义形式为
{}f()void,并允许使用任何(固定的)号码和(固定的)参数类型调用它?可能没有技术上的理由不允许它(出于某种“技术原因”的价值),我们只需要打破很多类型安全性。@Rup,因为它没有声明原型——它没有向调用者提供有关参数类型的信息。。。这是无法改变的,因为这是C语言中已建立的语义。请注意,甚至没有一种方法来声明(或定义)旧式函数。。。e、 你不能把
intsum(i,j)inti,j在头文件中。。。如果没有后续的
{
,这是一个语法错误。从C99标准来看,它到处都过时了:“使用带有单独参数标识符和声明列表的函数定义(不是原型格式参数类型和标识符声明器)是一个过时的功能。”由于C++中的参数类型是函数签名的一部分,而C++中的旧类型定义不是原型,旧的函数声明没有语法包含参数类型,所以它缺少的主要原因是C++。