为何某些公司不允许使用C++STL

2023-05-16

点击蓝字

77afb261ecd8a8d5a25b6f8b664a7966.png

关注我们

最初开始禁用 C++ STL,是因为早期项目编码实践中留下的惯例,被后来的程序员继承下来。老项目中这种选择尤其地多。不过如果有人将其上升到公司行为在不同项目中全面禁用 STL,则没有必要,而且我倾向于做这种决定的人并不理解 C++ 编译系统。

一般来说,项目中禁用 C++ 多见于两种具体场景:项目的产出产品为函数库 OR需要引用第三方函数库。

具体地来说,有三个主要原因:

1、第一个原因是二进制边界混乱。

对需要在项目中使用第三方函数库的程序员来说,二进制边界是个头痛的问题。C++ 在这一方面本身就处理得不算好,加上模板后起到的是雪上加霜的后果。没有经验的程序员会贪图方便而在公开头文件中使用 C++ 模板,如果这时调用方的编译器选项设置或 STL 版本和编译方不同,那么就可能出现同样的头文件在不同的环境下二进制布局不符的情况。

顺便说一句,在过去十年里,各个主流编译器附带的 STL 版本变化节奏不慢,所以这种由于编译环境不同而导致的 bug 并不算罕见,但缺乏汇编知识的用户难以排查。

ff922665122a922e889ab3cab77fbf56.jpeg

2、第二个原因是不愿使用异常。

如今除了 Android 上的 STLPort 关闭异常,大部分主流 C++ STL 实现里都无法脱离异常使用 STL。异常带来的问题主要是两个:性能下降,代码膨胀。这几年 C++ 编译器在性能方面的改进很多,good path 的性能问题已经基本没有,但代码膨胀问题却没有太多改善,甚至这个性能问题的一部分解决方案就是以代码膨胀为代价。我写过一篇短文比对过 Android 上 gcc 4.6 在有无异常的情况下的汇编代码逻辑,可以看到,启动异常时生成的汇编代码量多出了相当一部分(我的例子中是 50%),用于处理各种隐含代码中的异常问题。这一条在手机系统中有时候会引起意想不到的麻烦,比如软件升级后导致 app 在低存储容量的手机中安装失败。顺便说一句,这个问题并不是 gcc 独有,clang 上生成的代码是一样的。参考:http://dummydigit.net/posts/2014-01-01-23-30-1.html

cfeb35c3295ae9bc4a0934be574af14d.jpeg

3、最后一个原因是C兼容。

严格地说,STL 在这个问题上算是躺枪,这个坑在很多具体的场景中也是因为异常而引入,但这个问题的麻烦程度比前两个问题更高。比如 gcc 在编译纯 C 代码时默认关闭 -fexceptions 选项,因此这样编译出来的代码中没有异常处理相关的栈展开。如果某个 C++ 项目引用了一个第三方 C 项目,它很难确保那个 C 项目给出的二进制代码中正确进行了异常处理并保证代码服从异常安全操作。这种场景下混用 C/C++ ,就可能在抛出异常时莫名其妙地崩溃或者出现 C 代码区段中的资源泄漏,特别是 expat 那种大量利用回调的代码结构。要规避这种风险并非不可能,但需要 C 的架构部分做修改,比如使用 DOM 那种树形结构,这种做法对历史项目而言又很难办到。换言之,如果一个项目出于种种原因需要保持 C 兼容,而 STL 就属于其中一个不可控的变数,与其相信程序员不犯错,不如直接禁用更可控一些。参考:Code Gen Options

要解决二进制相关的问题很简单:整个项目的所有相关代码在同一个代码基上编译,强制打开编译选项添加异常代码,并去除一切二进制依赖。但对很多小公司来说,引入这样的系统对配置管理的要求较高。如果一部分依赖关系来自自己并不了解的第三方代码,轻易修改编译选项可能带来的风险与第三方代码库的规模成正比。退一步说,即便团队里真的有强大的配置管理工程师能够搞定一切,他们也不会有能力解决代码膨胀问题,除非他们有权决定换一个编译器。相比之下,前面朋友所说的所谓性能或者编译出错时糟糕的可读性,在我看来反倒是次要因素,而且这些缺陷都正在新的编译器中逐步得到解决或改善,比如 clang。

所以那些选择禁用 STL 的早期项目负责人,总有一些确实的理由,没有人那么别扭地想跟开发效率过不去。至于后来的人是真的仔细想过这些细节还是人云亦云,那是另一个问题。

*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

88447c2f5724a2a9bc3417c2f3115402.png

610c9ab8889ba165424047e18036e80b.gif

戳“阅读原文”我们一起进步

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为何某些公司不允许使用C++STL 的相关文章

  • 使用连续内存并具有保留功能的映射和集合

    我使用了几张地图和套件 缺乏连续内存以及大量的分配 解除 是性能瓶颈 我需要一个主要与 STL 兼容的映射和集合类 它可以将连续的内存块用于内部对象 或多个块 它还需要有一个reserve函数 以便我可以预先分配预期的大小 在我自己编写之前
  • Linux 与 Windows std::map 赋值构造函数(为什么有这样的差异?)

    我在 Linux Ubuntu 中编写的 C 应用程序中目睹了一些意外行为 我将构造一个带有参数的对象 然后使用赋值运算符将该对象的副本放入 std map 中 我写了一个简单的程序来演示这种情况 include
  • STL 中 next_permutation 的 Python 实现

    next permutation 是一个 C 函数 它给出字符串按字典顺序排列的下一个排列 有关其实现的详细信息可以从这篇非常棒的文章中获得 http wordaligned org articles next permutation ht
  • 如何从priority_queue中删除不在顶部的元素?

    在我的程序中 我需要从优先级队列中删除不在顶部的元素 可以吗 如果没有 请建议一种除了创建自己的堆之外的方法 标准priority queue
  • 如何使用类初始化 STL 向量/列表而不调用复制构造函数

    我有一个 C 程序 它使用包含类实例的 std list 如果我打电话 例如myList push back MyClass variable 它经历创建临时变量的过程 然后立即将其复制到向量 然后删除临时变量 这远没有我想要的那么高效 而
  • 哪个STL容器?

    我需要一个容器 不一定是 STL 容器 它可以让我轻松执行以下操作 在任意位置插入和移除元素 通过索引访问元素 以任意顺序迭代元素 I used 标准 列表 但它不会让我在任何位置插入 确实如此 但为此我必须迭代所有元素 然后在我想要的位置
  • 从 std::heap 中间删除一个元素

    我使用优先级队列作为调度程序 但有一个额外的要求 我需要能够取消预定的项目 这相当于从优先级队列中间删除一个项目 我不能使用std priority queue因为对除顶部之外的任何元素的访问都受到保护 我正在尝试使用algorithm的堆
  • 查找向量中最近的点

    给定一个具有多个值的排序向量 如下例所示 std vector
  • 通过值获取 std::queue 中元素的索引

    有没有一种简单的方法来获取元素在 a 中的位置std queue通过它在 C 中的值 例如 std queue
  • 迭代器后继者

    我想用另一个迭代器 同类 的后继者初始化一个迭代器 任意类型 以下代码适用于随机访问迭代器 但不适用于前向或双向迭代器 Iterator i j 1 一个简单的解决方法是 Iterator i j i 但这不起作用初始化语句for 循环的
  • 区分映射和集合的模板

    在创建代码时common for set unordered set map and unordered map 我需要几种方法 其中处理实际上是不同的 我的问题是让编译器推断出要使用哪个实现 考虑这个例子 include
  • 专门化 STL 算法,以便它们在可用时自动调用高效的容器成员函数

    STL 具有全局算法 可以在任意容器上运行 只要它们支持该算法的基本要求 例如 某些算法可能要求容器具有随机访问迭代器 例如向量而不是列表 当容器具有比通用算法更快的执行方式时 它会提供具有相同名称的成员函数来实现相同的目标 就像提供自己的
  • 如何在 g++ 中使用不同的 STL

    我想对 g 使用不同的 STL 而不是其默认的 libstdc 做到这一点最简单的方法是什么 我发现 nostdinc 标志禁止 g 查找其 STL 标头 但这只是编译时的事情 它仍然会使 g 链接到它自己的 STL 所以我需要找到一种方法
  • 如何将 list 对象附加到另一个对象

    在 C 中 我有两个list
  • 使用 STL 迭代器而不初始化它

    我想做这样的事情 container iterator it NULL switch eSomeEnum case Container1 it vecContainer1 begin break case Container2 it vec
  • 在 boost 元组、zip_iterator 等上使用 std::get 和 std::tie

    我有哪些使用选择std get lt gt and std tie lt gt 与增强结构一起 例子 我想使用基于范围的 for 循环在多个容器上进行迭代 我可以实施zip函数 它使用boost zip iterator include
  • C++ STL type_traits 问题

    我正在看最新的C9讲座 http channel9 msdn com Shows Going Deep C9 Lectures Stephan T Lavavej Standard Template Library STL 10 of 10
  • 带有自定义分配器的 std::string

    所以我目前正在编写一个内存调试器 为此我需要 stl 容器对象来使用未跟踪的分配器 我的整个代码库中都散布了 std string 因此我将其键入以使用未跟踪的分配器 typedef std basic string
  • 我应该使用函数还是无状态函子?

    这两段代码做同样的事情 如您所见 它将用于排序函数 哪个更好 我通常写后一种 但我看到一些程序员像以前那样做 struct val lessthan binary function
  • std::list::clear 是否会使 std::list::end 迭代器无效?

    检查这个代码 include stdafx h include

随机推荐

  • STM32系列(HAL库) ——使用串口打印的3种方式

    一 前期准备 1 硬件 xff1a STM32C8T6最小系统板USB TTL串口模块ST Link下载器 2 软件 xff1a keil5 IDEcubeMX 二 cubeMX配置 1 配置RCC 选择外部时钟源 2 配置SYS Seri
  • C#多线程编程:线程基础

    原文链接 xff1a https www cnblogs com wyt007 p 9486752 html 创建线程 static void Main string args Thread t 61 new Thread PrintNum
  • ROS 控制Innfos机械臂简单例子

    include lt ros ros h gt include lt image transport image transport h gt include lt sensor msgs image encodings h gt incl
  • 使用CMake和Visual Studio搭建工程并引入OpenCV库

    前言 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 在之前的Windows平台下OpenCV的编译与安装 Mega Li的博客 CSDN博客 nbsp 中介绍了Windows平台中使用CMake编译Open
  • UART通信中流控RTS和CTS的理解

    一 流控 xff0c 顾名思义就是流量控制的意思 目的是协调收发双方 xff0c 使数据不会丢失 如果UART只有RX TX两个信号 xff0c 要流控的话只能是软流控 xff1b 如果有RX xff0c TX xff0c CTS xff0
  • JVM虚拟机栈

    虚拟机栈 每个线程在创建时都会创建一个虚拟机栈 xff0c 其内部保存一个个栈帧 xff0c 对应一次次java方法的调用 xff08 线程私有 xff09 生命周期与线程一致 作用 xff1a 主管java线程的运行 xff0c 保存局部
  • C++之串口通讯

    C 43 43 串口操作 简介代码头文件源码文件 示例创建两个虚拟串口用串口调试助手连接COM2来接数据编写测试代码发送数据结果 总结 简介 串行接口简称串口 xff0c 也称串行通信接口或串行通讯接口 xff08 通常指COM接口 xff
  • 用keil写程序时出现“C(162): error C249: 'DATA': SEGMENT TOO LARGE“的错误

    如果定义的数组不用更改就用 uchar code XX 10 61 根据数据的用处 xff0c 可以有以下几种选择 xff1a data xff1a 直接寻址 的片内RAM区低128B xff08 00H 7FH xff09 bdata x
  • ROS 与 Box Turtle、C Turtle、Indigo Igloo 、Jade Turtle 、Kinetic Kame 、Melodic Morenia、Noetic Ninjemys关系

    如果没有错的话相当于这个些都是ros的版本 xff0c 就是不同时期叫的名字不一样 xff0c 用于区别不同的版本 因为也是初学者 xff0c 都还没入门 xff0c 也是网上找的资料 xff0c 并根据自己的理解写的 xff0c 如果有错
  • C语言——VS编译器下程序运行结果闪退解决方法

    C语言 VS编译器下程序运行结果闪退解决方法 学习C语言的过程中可能会遇到这样的问题 xff0c 程序调试的时候没有错误 xff0c 可是在运行结果的时候会发现程序结果闪退 xff0c 导致看不到结果 在此 xff0c 本文总结对比了几种有
  • Gazebo 加载xacro文件和URDF文件的方式

    版权声明 xff1a lt 本博客所有内容均为自己在学习工作中的总结 摘录等 转载请注明出处 如有侵权请联系删除 gt https blog csdn net xuehuafeiwu123 article details 71108959
  • Gazebo显示加载xacro模型文件---改变模型的颜色注意事项

    在xacro文件中 xff0c 有下列语句是修改模型颜色的 xff1a 例 xff1a lt link name 61 34 base link 34 gt lt visual gt lt geometry gt lt box size 6
  • Gazebo中sdf文件和urdf和xacro文件的区别

    sdf文件 urdf文件和xacro文件都是模型文件 xacro文件是urdf文件的改进版 xff0c urdf文件只能在rviz等中显示 xff0c 不能在仿真器中显示出来 xacro文件可以在gazebo仿真器中显示出来 xff0c 相
  • Gazebo的xacro文件添加各种plugins

    官网地址 xff1a http gazebosim org tutorials tut 61 ros gzplugins Tutorial Using Gazebo plugins with ROS Gazebo plugins give
  • ROS中spawn_model方式加载xacro文件,设置模型的位置(xyz,rpy)

    例如加载turtlebot机器人launch文件如下 xff1a 在gazebo仿真中最后都是通过这种方式加载xacro文件的 lt launch gt lt arg name 61 34 base 34 gt lt arg name 61
  • BT1120

    BT1120是高清晰度电视 HDTV 演播室信号数字接口 图像数据是怎么用二进制数据组织在一起的呢 xff1f 个人理解 xff1a 在BT1120标准中说明的图像数据指的是图像的有效尺寸的数据 因为我们看到编码信号包括图像数据和图像基准码
  • 2021-10-22 常用的串口通讯协议

    串口通讯是什么 学术解释是 xff0c 通过总线在一个时间点连续发送一位数据的方法 如同弓箭手频繁射出弓箭一般 xff0c 嗖 嗖 嗖 串口通讯协议是什么 说的大白话一点 xff0c 就是串口通信时所使用的协议传输方式 串口通讯协议有几种呢
  • curl 命令详解

    curl 是一种命令行工具 xff0c 作用是发出网络请求 xff0c 然后获取数据 xff0c 显示在 34 标准输出 34 xff08 stdout xff09 上面 它支持多种协议 xff0c 下面列举其常用功能 一 查看网页源码 直
  • RS485/云台控制(PTZ)学习文档

    RS485 云台控制 xff08 PTZ xff09 学习文档 zxf 一 项目任务 xff1a 在linux环境下通过RS485串口实现对云台镜头的各种控制 xff08 包括摄像头的打开 xff0c 关闭 xff0c 各个方向的运动及运动
  • 为何某些公司不允许使用C++STL

    点击蓝字 关注我们 最初开始禁用 C 43 43 STL xff0c 是因为早期项目编码实践中留下的惯例 xff0c 被后来的程序员继承下来 老项目中这种选择尤其地多 不过如果有人将其上升到公司行为在不同项目中全面禁用 STL xff0c