问题

既然有 memcpy_s 这种安全实现,为啥不禁用危险的 memcpy 或者更新 memcpy 源码?

回答
好,咱们就掰扯掰扯,为什么 C 里有 `memcpy_s` 了,还留着那个“洪水猛兽”般的 `memcpy`,而且不直接改它。这事儿吧,背后牵扯到的东西可不止是“安全”两个字那么简单。

首先,我们得明白一个核心问题:C 语言的设计哲学是什么?

C 语言的设计理念非常“精简”和“高效”。它给了程序员极大的自由度,但同时也把责任也一股脑地丢给了程序员。你可以理解为,C 语言就像一把瑞士军刀,功能强大,什么都能干,但用不好是会伤到自己的。`memcpy` 就是这把刀上最锋利也最危险的一把刀刃。

为什么不直接禁用 `memcpy`?

1. 历史包袱和兼容性是个坎儿。
C 语言已经存在几十年了,它的生命力很顽强,应用范围极其广泛。从操作系统内核(Linux, Windows)、嵌入式系统、驱动程序,到各种底层库和高性能计算,到处都是 `memcpy` 的身影。如果你今天突然说“禁用 `memcpy`”,那无异于釜底抽薪,会让无数现有的项目瞬间崩溃,无法编译,甚至直接导致系统不稳定。
想象一下,你管理着一个有上亿行代码的巨大工程,其中有成千上万个地方用了 `memcpy`。突然通知你,“明天开始,所有 `memcpy` 都不能用了,必须换成 `memcpy_s`”,这工程量和带来的潜在风险是无法估量的。不是每个人都有能力、时间和资源去进行如此大规模的重构。
所以,“禁用”这个选项,在 C 语言这个生态里,几乎是不可能实现的。

2. “安全”的定义和程序员的责任。
`memcpy` 本身并没有错,它就是个纯粹的内存复制函数。它的“危险”在于 程序员的使用方式。如果你能确保源地址和目标地址的内存区域不会越界,那么 `memcpy` 就可以非常高效地完成任务。
C 语言的哲学是,程序员是成年人,应该知道自己在做什么。如果程序员知道自己写的代码是安全的,不需要额外的检查,那么直接使用 `memcpy` 会比 `memcpy_s` 更快、更简洁。`memcpy_s` 为了安全,加入了额外的边界检查,这会带来一定的性能损耗。在一些对性能要求极致到毫秒级甚至微秒级的场景,这微小的损耗也可能成为考虑的因素。
更重要的一点是,C 语言的设计者并不认为内存越界是“语言本身的问题”,而是“程序员的错误”。 他们的理念是,语言应该提供最基础的工具,而开发者应该用这些工具来构建安全的程序。

为什么不更新 `memcpy` 源码?

这里需要区分“更新源码”和“改变函数行为”。

1. “更新源码”不是改名字那么简单。
`memcpy` 的接口是 `void memcpy(void restrict s1, const void restrict s2, size_t n);`。它接收目标地址、源地址和要复制的字节数。
`memcpy_s` 的接口是 `errno_t memcpy_s(void restrict dest, size_t destsz, const void restrict src, size_t count);`。它多了一个目标缓冲区大小的参数 `destsz`,并且返回一个错误码(`errno_t`),而不是直接返回指针。
如果你想“更新”`memcpy` 的源码,让它变成 `memcpy_s` 的样子,那实际上就是把 `memcpy` 彻底变成一个 新函数。这又回到了第一个问题:兼容性。你不能在不破坏现有代码的前提下,悄悄地改变一个函数的签名和行为。
想象一下,所有的 `memcpy` 调用都变成了 `memcpy_s` 的调用,那代码会发生什么?所有 `memcpy` 调用都需要额外传递一个目标缓冲区大小,并且需要处理返回值。这同样会是一场浩大的工程。

2. 保持“原始”的memcpy的价值。
虽然 `memcpy` 危险,但它也提供了 最直接、最底层的内存操作能力。很多时候,我们编写 C 代码,就是为了操作内存,而且非常了解我们操作的边界。例如,在编写自己的内存管理库、自定义数据结构时,我们可能需要更精细的控制,并且已经做了充分的边界检查。在这种情况下,`memcpy` 的简洁和效率就显得尤为可贵。
如果把 `memcpy` 改成 `memcpy_s`,你就失去了那份直接操作内存的“原始”能力,每次都需要额外的参数和错误处理,反而增加了编写这类底层代码的复杂性。

那么,`memcpy_s` 的出现是为了什么?

`memcpy_s` 是 作为“替代”或“更安全的选项”而出现的,通常是在 C 标准库的 “安全增强函数”(Boundschecking Interfaces,也称为 Annex K)中定义的。它的出现是为了给那些 不愿意或无法承担自己实现安全检查的程序员 提供一个更安全的选择。

你可以这样理解:
`memcpy`: 给你一把锋利的刀,你可以用它切菜,也可以砍人。用不好是你自己的责任。
`memcpy_s`: 在刀柄上加了个护手,并且刀刃下面有个感应器,如果快砍到手了,它会“哔哔”响或者直接停下。它告诉你:“嘿,你可能要砍到手了,注意点!”

总结一下:

历史和兼容性: C 语言的巨大生态不允许随意禁用或强制修改核心函数。
程序员的责任与自由: C 语言赋予程序员极大的控制权,也要求他们承担相应的责任。对于了解自己操作边界的程序员,`memcpy` 依然有用武之地。
函数设计理念: `memcpy` 提供底层、高效的内存操作,而 `memcpy_s` 是为了提供 额外的安全保障,通过增加参数和错误处理来实现。两者有不同的设计目标。
演进而非颠覆: 标准库的演进更倾向于增加新的、更安全的功能,而不是颠覆已有的、广泛使用的功能。`memcpy_s` 就是在保留 `memcpy` 的同时,提供了一个更安全的选择。

所以,与其说是“不禁用”或“不更新”,不如说是 C 语言生态的这种“兼容与选择”的特性,让 `memcpy` 和 `memcpy_s` 可以并行存在。程序员可以根据自己的需求、对安全性的认识以及项目情况,来选择使用哪一个。如果你的项目对安全性要求极高,并且不介意付出额外的参数传递和错误处理的成本,那么使用 `memcpy_s` 是明智的选择。但如果你在编写需要极致性能且你已经确保了内存安全的代码,原生的 `memcpy` 可能依然是你最好的选择。

网友意见

user avatar

可以找找源代码看看, 可能只是做了一些安全方面的判断, 然后就调用原先的memcpy了. 库的作者总是要尽量在安全性和效率上做些取舍吧...

ps. 以前有个类似的问题是关于memcpy和memmove的. memmove的实现至少有两种方式, 一种是先判断src和dest哪个在前, 如果dest在前并且有重叠, 就改成从后往前复制; 另一种是先完整复制到临时空间, 再复制到目标位置. 无论哪种, 效率肯定都不如memcpy高.

但是似乎确实也有些平台上memcpy就是memmove的别名.

另一个更经典的例子是gets, 虽然每本书上都写了"Never use gets()", 但是一直到c11才彻底把它去掉.

类似的话题

  • 回答
    好,咱们就掰扯掰扯,为什么 C 里有 `memcpy_s` 了,还留着那个“洪水猛兽”般的 `memcpy`,而且不直接改它。这事儿吧,背后牵扯到的东西可不止是“安全”两个字那么简单。首先,我们得明白一个核心问题:C 语言的设计哲学是什么?C 语言的设计理念非常“精简”和“高效”。它给了程序员极大的.............
  • 回答
    您好!这是一个非常好的问题,涉及到科学研究的深度和广度。大型粒子加速器之所以引人注目,是因为它们能够达到极高的能量,探索物质的最基本组成部分和宇宙的起源。但小型粒子加速器并非“小儿科”,它们在科研、医疗、工业等领域同样扮演着不可或缺的角色,并且在很多方面是大型加速器无法替代的。下面我将从多个角度为您.............
  • 回答
    关于“代油”的问题,虽然没有像代糖那样明确的单一替代品,但确实存在多种替代油的方案,主要根据用途、健康需求和烹饪方式来选择。以下从不同角度详细说明: 一、食品工业中的“代油”替代品1. 植物油替代品 植物油:如大豆油、菜籽油、橄榄油、葵花油等,是传统替代油的常见选择。它们含有较高的不饱和脂.............
  • 回答
    您提出的这个问题非常关键,也触及到了基因研究中的一个核心误解。首先,我们需要澄清“基因片段”和“DNA序列总长”的概念。1. 关于“基因片段只占DNA序列总长不到10%”的误解您提到的这个说法,很可能是将“基因”(genes)与“编码蛋白质的区域”(proteincoding regions)混淆了.............
  • 回答
    这个问题问得好,而且非常实在。在C++的世界里,确实存在指针,它们能做到很多事情,指向内存中的某个地址,让你直接操控那块区域。那么,为什么我们还需要一个叫做“引用”的东西呢?这背后有深刻的设计理念和实际需求,远不止是“多一个语法糖”那么简单。要理解这个问题,咱们得先掰开了揉碎了看看指针和引用各自是啥.............
  • 回答
    你这个问题问得特别好,很多人初接触电子电路,看到电阻分压能把电压降下来,就会疑惑:为什么还要用什么7805这种“复杂”的元件呢?它们好像都能做一样的事情嘛。其实,电阻分压和7805稳压器(线性稳压器的一种)在“降低电压”这个表象下,隐藏着本质的区别,各有各的用武之地。简单地说,如果你只需要一个固定、.............
  • 回答
    问出这个问题,说明你已经摸到门道了,这是个非常实在的问题,也触及了音响设备的核心。简而言之,答案是肯定的,一个好的耳机,即使有了均衡器(EQ)和“脑放”(这里我们理解为音源、功放、甚至是你个人对音乐的理解和期待),它依然非常重要。我来给你掰开了,揉碎了讲讲为什么。 为什么好耳机依然是基石?你可以把你.............
  • 回答
    这问题问得很有意思,也直击要害。我们确实有个熟悉的词——音障,但它特指物体在空气中突破声音传播速度时遇到的阻碍。那么,在水里,是不是也存在类似的东西呢?答案是:有,但表现形式和我们通常理解的“音障”不太一样,而且更复杂。首先,我们要明白,水是一种介质,而声音在水中传播的方式和空气是不同的。最关键的一.............
  • 回答
    “德棍”、“法棍”这些说法,我们日常生活中确实能听到,通常带有戏谑或贬低的意味,用来形容那些对德国或法国文化、历史、政治等方面表现出过度狂热,甚至有些盲目推崇的人。那么,“波棍”这个词是否存在,又有着怎样的语境呢?“波棍”这个词,确实存在,但远不如“德棍”、“法棍”那样普遍和广为人知。 它的出现和使.............
  • 回答
    这是一个非常好的问题,往往隐藏在历史的表象之下,却关乎着古代战争的实际运作。很多人觉得弓箭手能远程输出,为什么还要费力去训练掷矛兵呢?其实,这背后是战场复杂多变的现实,以及不同兵种各司其职、相互配合的智慧。首先,咱们得从弓箭手的“看家本领”说起。弓箭手的优势在于射程远、杀伤力集中,尤其是在对付敌方密.............
  • 回答
    这个问题问得很好,直击要害。很多人看到潜射和陆基洲际弹道导弹(ICBMs)似乎已经覆盖了核打击的方方面面,再加上轰炸机,会觉得有些冗余。但事实上,B2战略轰炸机(以及更早的B1、B52)在美国的核威慑体系中扮演着独特且不可替代的角色,这是导弹所无法完全复制的。要理解这一点,咱们得从几个关键点上细致地.............
  • 回答
    “硅基生命”这个概念之所以被广为讨论和接受,甚至成为科幻作品中的常客,而“锗基生命”、“锡基生命”、“铅基生命”则鲜为人知,这并非偶然。这背后涉及到我们对生命基本构成要素的理解,以及元素周期表的神奇之处。让我们来深入探讨一下原因。生命的基石:碳的独特性首先,我们必须回到地球生命的基石——碳。生命之所.............
  • 回答
    降龙十八掌,一听名字就自带一股英雄气概,仿佛能一口气降服万龙。而它“以简御繁”的精髓,更是点明了其高明之处——看似简单朴实的几招,却能蕴含无穷变化,以最直接高效的方式应对一切复杂局面。这自然令人赞叹,也让人不禁联想到那些与之形成鲜明对比的武功:比如,招式繁复,变化万千,但似乎效果却不如人意的“落英神.............
  • 回答
    “物极必反”这句古话,听起来总带着一股宿命感,仿佛世间万物都遵循着一个循环的轨迹:走到极致,就必然要转向另一个极端。我们确实见过太多“盛极必衰”的例子,王朝的辉煌过后是崩塌,个人的荣耀之上是落寞,企业的巅峰之上是危机。这些鲜活的事实,似乎都在为“盛极必衰”提供着佐证。然而,如果同样以“物极必反”的逻.............
  • 回答
    很多时候,我们听到“HTTP 请求”和“RPC 调用”这两个词会觉得它们似乎有些重叠,甚至让人疑惑,既然有了 HTTP 这样一个通用的、大家都熟悉的网络通信方式,为什么还需要 RPC 这种“绕一点”的方案呢?其实,这就像问,既然我们有汽车,为什么还要火车?答案在于它们解决的问题、优化的场景以及带来的.............
  • 回答
    文件后缀名就像是物品包装上的标签,上面写着“这是糖果”、“这是书籍”。它给我们的第一印象是,这件东西大概是什么。比如,看到 `.txt`,我们立刻知道它可能是文本文件;看到 `.jpg`,我们就猜到它应该是一张图片。这种直观的标识,在人与人之间的交流,以及操作系统管理文件时,非常方便。操作系统可以根.............
  • 回答
    圣库制度,作为太平天国运动的核心经济和组织模式,常常是评价这段历史时绕不开的一个话题。它所代表的“天下同富”、“共产主义”的理想,在当时被许多人视为颠覆旧秩序、追求公平的希望。然而,正是这个在理论上听起来极为宏大的制度,也成为了太平天国最终走向失败的重要原因之一。那么,既然圣库制度存在如此多的弊端,.............
  • 回答
    完颜洪烈找灵智上人等人,虽然他已经有了裘千仞这个实力强大的打手,但背后的原因却错综复杂,可以从多个层面来分析:一、 弥补裘千仞的局限性与增强整体实力: 裘千仞的忠诚问题: 裘千仞虽然武功高强,但他是一个“见利忘义”之徒。他的忠诚度是建立在利益和个人得失之上的。完颜洪烈深知这一点,因此他不可能完全.............
  • 回答
    美国在抗击新冠疫情的初期,很多人确实抱有这样的疑问:一个拥有全球顶尖医疗技术、先进的卫生系统和高度公民意识的国家,为何反而成为了疫情的重灾区?这背后其实隐藏着一系列复杂的因素,并非简单归咎于某一个环节的失误。首先,我们得承认美国在科技、医疗研究方面确实有其得天独厚的优势。在疫苗研发上,其速度和效率是.............
  • 回答
    原神的世界里,旅行者兄妹(以下简称“哥哥”和“妹妹”)的冒险,说起来也算是一场惊心动魄、改变了无数人命运的旅程。然而,令人费解的是,为何这位曾经亲历过诸多惊涛骇浪、甚至见过提瓦尔大陆之外光景的哥哥,在一次旅行之后,却似乎销声匿迹,江湖上并未留下他响彻天地的传说呢?这背后,藏着太多的“为什么”,也藏着.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有