C++核心准则F.55 不要使用可变参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++核心准则F.55 不要使用可变参数相关的知识,希望对你有一定的参考价值。


F.55: Dont use ​​va_arg​​ arguments

F.55 不要使用可变参数

Reason(原因)

Reading from a ​​va_arg​​ assumes that the correct type was actually passed. Passing to varargs assumes the correct type will be read. This is fragile because it cannot generally be enforced to be safe in the language and so relies on programmer discipline to get it right.

从va_arg中读出内容的处理假设实际传递的数据类型是正确的。传递可变参数的处理假设数据会按照正确的类型被读取。由于通常这两种假设都不能在语言中强制达成安全,只能依靠编程规范以保证其正确。因此说都是脆弱的。

Example(示例)

 

int sum(...) 
// ...
while (/*...*/)
result += va_arg(list, int); // BAD, assumes it will be passed ints
// ...

sum(3, 2); // ok
sum(3.14159, 2.71828); // BAD, undefined
template<class ...Args>
auto sum(Args... args) // GOOD, and much more flexible
return (... + args); // note: C++17 "fold expression"

sum(3, 2); // ok: 5
sum(3.14159, 2.71828); // ok: ~5.85987

译者注:代码中使用了两种现代C++的新特性,一个是C++11中引入的可变参数模板(variadic template),另一个是C++17引入的折叠表达式(fold expression)。

Alternatives(备选方案)

  • overloading
    重载
  • variadic templates
    可变参数列表
  • ​variant​​​ arguments
    variant(C++17引入的变体数据,译者注)类型参数。
  • ​initializer_list​​​ (homogeneous)
    初始化列表(同类数据的情况)(C++11引入)

Note(注意)

Declaring a ​​...​​ parameter is sometimes useful for techniques that dont involve actual argument passing, notably to declare "take-anything" functions so as to disable "everything else" in an overload set or express a catchall case in a template metaprogram.

定义一个...参数在无法决定实际参数类型时一种有用的技术,尤其是定义可以接受任何东西的函数以便在重载版本中禁止“任何其他的东西”或者在模板元程序中表示包罗万象的容器。

Enforcement(实施建议)

  • Issue a diagnostic for using ​​va_list​​, ​​va_start​​, or ​​va_arg​​.
    发起对使用va_list,va_start或者va_arg的检查。
  • Issue a diagnostic for passing an argument to a vararg parameter of a function that does not offer an overload for a more specific type in the position of the vararg. To fix: Use a different function, or ​​[[suppress(types)]]​​.
    发起针对以下情况的检查:向函数的可变参数可变参数传递单独的实参,而且不存在在可变参数位置定义了特定数据类型参数的重载函数。
    修改建议:使用不同的函数或者[[抑制((类型准则群组))]]

 

觉得本文有帮助?欢迎点赞并分享给更多的人!

阅读更多更新文章,请关注微信公众号【面向对象思考】

以上是关于C++核心准则F.55 不要使用可变参数的主要内容,如果未能解决你的问题,请参考以下文章

C++核心准则边译边学-F.17 输入/输出参数传递非常量引用

C++核心准则边译边学-I.11 永远不要使用原始指针或引用传递所有权

C++核心准则C.9:最小限度暴露成员

C++核心准则C.7:不要在一条语句内声明类或枚举值的同时又定义该类型的变量

C++核心准则边译边学-F.16 对于输入参数来说,拷贝代价小的传值,其他传递const参照

c++的核心准则