C++ 可变参数函数声明中省略逗号
Comma omitted in variadic function declaration in C++
我习惯这样声明可变参数函数:
int f(int n, ...);
在阅读The C++ Programming Language时发现书中的声明省略了逗号:
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++?
与int f(int n, ...);
和int f(int n...);
一样,可以see,, ...
和...
具有相同的含义。逗号是可选的。
但是这个 int printz(...);
在 C++
中有效,而 int printz(,...);
无效(至少一个命名参数必须出现在省略号参数之前)。这就是为什么您只能 (...)
,即使传递给此类函数的参数不可访问。
根据 C++ 标准的第 8.3.5.4 节 (current draft):
Where syntactically correct and where “...” is not part of
an abstract-declarator, “, ...” is synonymous with “...”.
简而言之,在 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 引入可变参数模板,第二个声明更有可能是程序员错误,而不是懒惰地省略逗号。因此,有人提议将后者从语言中删除 (P0281), but it was apparently 。
我记得当时,C++ 确实如您所记定义了可变参数函数符号。后来,快速发展的 C 语言(从 K&R 到 ANSI 的旅程)引入了 prototypes 或 new-style function declarations ,它们也在括号内声明了参数在函数名称之后。但是,有两个显着的区别:省略号前的逗号,以及需要 (void)
的可憎性来指示空参数列表(以保持空括号的向后兼容性作为 旧样式声明)。
翻阅我的档案,我发现 The C++ Programming Language 原版 "reprinted with corrections July 1987" 显示:
参数声明列表:
arg-声明列表opt ...
opt
arg-declaration-list:
arg-declaration-list ,
argument-declaration
参数声明
没有形式 接受现在可选的逗号。请注意,arg-declaration-list 是一个逗号 分隔的 ,这不会在列表之后和下一个(不同的)事物之前提供逗号。
这是最自然的写法。如果你想要一个逗号,你需要在第一个产品中明确地, ...
,作为两个不同的(可能是空格分隔的)标记。
随着 C 在适当标准化方面的努力取得进展,C++ 编译器也开始接受 C 版本,以便轻松使用 C 标准头文件。
为什么 C 语言的设计者要添加逗号,因为它暗示省略号作为假参数占位符的语法作用不太合理?我一直没发现。
我习惯这样声明可变参数函数:
int f(int n, ...);
在阅读The C++ Programming Language时发现书中的声明省略了逗号:
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++?
与int f(int n, ...);
和int f(int n...);
一样,可以see,, ...
和...
具有相同的含义。逗号是可选的。
但是这个 int printz(...);
在 C++
中有效,而 int printz(,...);
无效(至少一个命名参数必须出现在省略号参数之前)。这就是为什么您只能 (...)
,即使传递给此类函数的参数不可访问。
根据 C++ 标准的第 8.3.5.4 节 (current draft):
Where syntactically correct and where “...” is not part of an abstract-declarator, “, ...” is synonymous with “...”.
简而言之,在 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 引入可变参数模板,第二个声明更有可能是程序员错误,而不是懒惰地省略逗号。因此,有人提议将后者从语言中删除 (P0281), but it was apparently
我记得当时,C++ 确实如您所记定义了可变参数函数符号。后来,快速发展的 C 语言(从 K&R 到 ANSI 的旅程)引入了 prototypes 或 new-style function declarations ,它们也在括号内声明了参数在函数名称之后。但是,有两个显着的区别:省略号前的逗号,以及需要 (void)
的可憎性来指示空参数列表(以保持空括号的向后兼容性作为 旧样式声明)。
翻阅我的档案,我发现 The C++ Programming Language 原版 "reprinted with corrections July 1987" 显示:
参数声明列表:
arg-声明列表opt ...
opt
arg-declaration-list:
arg-declaration-list ,
argument-declaration
参数声明
没有形式 接受现在可选的逗号。请注意,arg-declaration-list 是一个逗号 分隔的 ,这不会在列表之后和下一个(不同的)事物之前提供逗号。
这是最自然的写法。如果你想要一个逗号,你需要在第一个产品中明确地, ...
,作为两个不同的(可能是空格分隔的)标记。
随着 C 在适当标准化方面的努力取得进展,C++ 编译器也开始接受 C 版本,以便轻松使用 C 标准头文件。
为什么 C 语言的设计者要添加逗号,因为它暗示省略号作为假参数占位符的语法作用不太合理?我一直没发现。