首页 文章详情

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

面向对象思考 | 597 2019-12-06 23:22 0 0 0
UniSMS (合一短信)

bf98ee4fd57953197833bdd105d7780c.webp

F.55: Don't 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); // oksum(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: 5sum(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 don't 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)]].

    发起针对以下情况的检查:向函数的可变参数可变参数传递单独的实参,而且不存在在可变参数位置定义了特定数据类型参数的重载函数。

    修改建议:使用不同的函数或者[[抑制((类型准则群组))]]


觉得本文有帮助?请分享给更多人

关注【面向对象思考】,每天前进一小步

有任何疑问,欢迎留言提问或讨论




面向对象设计,面向对象编程,面向对象思考!

159d1f50a75d7ad552b84bdb0e385668.webp

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter