专栏首页C++核心准则原文翻译C++核心准则F.55 不要使用可变参数

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

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); // 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 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)]]. 发起针对以下情况的检查:向函数的可变参数可变参数传递单独的实参,而且不存在在可变参数位置定义了特定数据类型参数的重载函数。 修改建议:使用不同的函数或者[[抑制((类型准则群组))]]

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

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

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


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

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则C.122:需要完全隔离接口和实现时用抽象类作为接口‍

    C.122: Use abstract classes as interfaces when complete separation of interface ...

    面向对象思考
  • C++核心准则C.168: 将重载的运算符定义在操作对象的命名空间内

    C.168: Define overloaded operators in the namespace of their operands

    面向对象思考
  • C++核心准则边译边学-序言

    C++核心准则(C++ Core Guidelines)是由C++语言两位大神级的人物发表的有关C++语言编程的指导性文件,目前还处于不断修改和完善的过程中。从...

    面向对象思考
  • gRPC in ASP.NET Core 3.0 -- Protocol Buffer(1)

    现如今微服务很流行,而微服务很有可能是使用不同语言进行构建的。而微服务之间通常需要相互通信,所以微服务之间必须在以下几个方面达成共识:

    solenovex
  • javascript当中Array对象用法

    1.Array对象 例 1.1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"...

    马克java社区
  • Javaweb-案例练习-5-商品数量修改和合计金额实现

    前面一篇完成了添加购物的功能,这篇来完善购物车页面上,修改商品数量和小计这两处地方的代码。

    凯哥Java
  • AT&T将谷歌云融入其NetBond for Cloud平台

    SDNLAB
  • 苹果开发者证书创建和设置真机调试

    用户1941540
  • 使用sublime实现python代码补

    最近一段时间一直都在学习python,很长一段时间内没有找到和是的IDE工具,Pycharm的话,对我来说稍微有点重量级了,因为平常其实是不怎么敲代码的,一般也...

    py3study
  • 思科技术 | GRE-V**的详细配置(含实验)

    3、GRE分为point-to-piont GRE和multipoint GRE两种

    网络技术联盟站

扫码关注云+社区

领取腾讯云代金券