逗号在C ++中的可变参数函数声明中省略
我习惯于像这样声明可变参数的函数:
int f(int n, ...);
在阅读C ++编程语言时,我发现书中的声明省略了逗号:
int f(int n...); // the comma has been omitted
看起来这个语法是特定于C ++的,当我尝试使用C编译器进行编译时出现此错误:
test.c:1:12: error: expected ';', ',' or ')' before '...' token int f(int n...);
写入int f(int n, ...)
和int f(int n...
)是否有区别?
为什么这个语法添加了C ++?
根据C ++标准的第8.3.5.4节( 当前草案 ):
在句法正确的地方,“…”不是抽象声明的一部分,“,…”与“…”是同义的。
简而言之,在C ++中...
(省略号)本身就是一个操作符,所以可以不用逗号来使用,但为了向后兼容,使用逗号是保留的。
目前,这两个声明都有相同的含义:
int f(int n, ...); int f(int n ...);
这导致了一个问题,即以下两个声明都是合法的,但却有着非常不同的含义:
template <class... T> void f(T...); // function template with parameter pack template <class T> void f(T...); // variadic function
一旦C ++ 11引入了可变参数模板,第二种声明更可能是程序员错误,而不是懒惰地忽略逗号。 因此,有人build议从语言中删除后者( P0281 ),但显然被拒绝了 。
用int f(int n, ...);
和int f(int n...);
正如你所看到的 ,两者, ...
和...
具有相同的含义。 逗号是可选的。
但是这个int printz(...);
在C++
是有效的,而int printz(,...);
不是(至less一个命名参数必须出现在省略号参数之前)。 这就是为什么你可以只是(...)
,即使传递给这个函数的参数是不可访问的。
就像我记得的那样,C ++确实定义了可变函数签名。 后来,快速发展的C语言(从K&R到ANSI的旅程)引入了原型或新型函数声明 ,该声明还在函数名称后面的parens中声明了参数。 但是,有两个显着的区别:椭圆之前的逗号和需要(void)
的憎恶来表示一个空的参数列表(为了保留空的参数作为旧式声明的向后兼容性)。
通过我的档案查看,我发现C ++编程语言原版“1987年7月更正转载”显示:
参数声明列表:
arg-declaration-list opt ...
opt
ARG-声明列表:
arg-declaration-list ,
参数声明
参数声明
没有forms接受现在可选的逗号。 请注意,arg-declaration-list是逗号分隔的 ,这不会在列表之后和下一个(不同的)之前提供逗号。
这是写这个最自然的方法。 如果你想要一个逗号,你需要显式的, ...
在第一个生产中,作为两个不同的(可能是空白分隔的)标记。
随着C正确标准化的努力取得进展,C ++编译器也开始接受C版本,以便于使用C标准头文件。
为什么Cdevise师在隐含椭圆的语法angular色作为假参数占位符时添加了逗号? 我从来没有发现。