当给定“const char *”作为第一个参数时,为什么 C 标准库函数“strchr”返回指向非常量的指针?

2024-01-10

使用 gcc/g++ 成功编译给定的代码示例。没有错误strchr调用,这显然分配了const char * to char *.

我发现了strchr被声明为char * strchr(const char *, int)在两个不同的来源pubs.opengroup.org http://pubs.opengroup.org/onlinepubs/7908799/xsh/strchr.html and cplusplus.com http://www.cplusplus.com/reference/cstring/strchr/

If strchr是为了抛弃常量而实现的,那么为什么会这样呢?

如果目标是提供同时适用于char * and const char *字符串 - 它可以使用两个不同的函数名称来实现。

你能对此给出更详尽的解释吗?

#include <string.h>

int main () {
    const char *str = "Sample string";
    char * ptr;

    //ptr = str;            //  Error: discards const qualifier - both on gcc and g++
    pch = strchr(str,'S');  //  Succeeds in assigning <const char *> to <char *>

    *pch = '4';             //  Runtime error: segmentation fault

    return 0;
}

使用 MSYS2/mingw-w64 gcc_v5.3.0 和 TDM-gcc32 v5.1.0 在 Win7 上尝试过。


你打电话时strchr with a char*你想要一个char*返回,这样您就不需要对结果进行强制转换。 C不支持函数重载,所以同样的strchr函数用于在a中进行搜索char*并在一个const char*。在所有情况下它都会返回一个非常量指针。如果你用一个来调用它const char*它基本上抛弃了const因此调用者有责任安全地使用它(例如,将结果分配给const char*立即,以避免对返回指针的任何不安全使用)。

如果目标是提供同时适用于 char * 和 const char * 字符串的函数 - 它可以使用两个不同的函数名称来实现。

是的,本来可以,但事实并非如此。原来的C版本不支持const根本没有,所以程序员有责任避免尝试修改字符串文字。如果使用不同的函数名称,那么它将破坏使用的现有代码strchr安全。这会减慢新产品的采用速度const关键字如果像这样的传统 C 代码突然停止编译:

char arr[] = "foo bar";
*strchr(arr, 'r') = 'z';

“C 的精神”是它不会试图阻止你做不安全的事情,编写正确的代码是你的工作。

In C++ strchr被重载以保持常量:

char* strchr(char*, int);
const char* strchr(const char*, int);

这意味着它会自动做正确的事情,并且更难意外地编写不安全的代码strchr.

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

当给定“const char *”作为第一个参数时,为什么 C 标准库函数“strchr”返回指向非常量的指针? 的相关文章

随机推荐

  • 无法绘制 svm 图。 terms.default(x) 中的错误:没有术语组件或属性

    我可以在我的数据集上使用 R 包 e1071 运行 svm 但我无法使用任何两个预测变量来绘制图表 即使在谷歌搜索了很多之后我也无法找到它的解决方案 请专家帮我解决这个问题 我有一个具有以下属性的数据集 gt dim fulldata 1
  • 使用 preg_match_all() 或更好的函数获取标签之间的所有文本?

    2010 June 11
  • Eclipse 代码格式化插件

    有人可以建议我一个插件来格式化 HTML 和 JAVA 代码并具有适当的缩进等吗 Eclipse 中有内置选项吗 使用源 gt 格式或 CTRL SHIFT F
  • CURLOPT_POSTFIELDS 的curl POST 格式

    当我使用curl via POST并设置CURLOPT POSTFIELD我一定要吗urlencode或者任何特殊格式 例如 如果我想发布 2 个字段 第一个和最后一个 first John last Smith 应该与curl一起使用的确
  • Objective-C 单例内存释放

    如果没有使用垃圾收集器 iPhone 环境 当我的应用程序终止时 我是否应该以某种方式释放共享对象 单例所基于的共享对象 当应用程序退出时 其所有内存都会被释放 因此 只要运行时不使用太多内存 释放对象并不重要 即使4 0策略发生变化 单个
  • 如何将逗号分隔值拆分为列

    我有一张这样的桌子 Value String 1 Cleo Smith 我想将逗号分隔的字符串分成两列 Value Name Surname 1 Cleo Smith 我只需要两个固定的额外列 您的目的可以使用以下查询来解决 Select
  • Groovy 和 Java 支持矩阵 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 为了了解哪些 Java Groovy 组合可以工作 我正在寻找一个可以显示此信息的矩阵 两者都开启ht
  • redis.lpush 一些项目

    In my node js脚本我有一个字符串数组 我想要LPUSH将这些字符串放入 Redis 队列中 我试过 var redis require redis createClient redis lpush queue 1 2 3 这会导
  • MongoDB ObjectID 对于会话 ID 来说是安全的

    我正在为 Happstack 服务器制作一个会话系统 并使用 mongoDB 进行持久存储 我想知道 MongoDB ObjectID 用作会话 ID 是否安全 一般来说 MongoDB ObjectID 是全局唯一的 因此如果您担心冲突
  • 使用push_back将整数放入字符串中

    我正在尝试使用以下代码将整数放入字符串中 int x 42 string num bool negative false if x lt 0 negative true x x 1 while x gt 0 num push back x
  • 如何从 SwiftyJSON 创建对象

    我有一个代码 可以解析 JSON 的问题列表 并且可以获得每个属性 如何迭代整个文件并为每个问题创建一个对象 class ViewController UIViewController var hoge JSON override func
  • 加速 mysql 转储和导入 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • AsyncWaitHandle.WaitOne 是否会阻塞 CLR 线程?或者它会创建一个 I/O 完成端口吗?

    我有这个问题 请问AsyncWaitHandle WaitOne阻塞CLR线程 或者它是否创建一个 I O 完成端口 例如 当我运行我的应用程序时 我启动一个任务 A 来初始化一些数据 当新请求到达时 我希望它们等到 A 完成 这样我就可以
  • 识别时间数据的差距

    EDIT 我找到了解决以下问题的方法 但是 它适用于小型数据集 但仍然会在大型数据集上创建错误输出 有人知道为什么吗 我找不到错误 这是代码 df continuous lt unlist lapply split df df ID fun
  • 如何在nginx中禁用http2

    due to this https openradar appspot com 26406397Safari 与 HTTP 2 和表单 POSTS 相关的问题 我想禁用通过 HTTP 2 提供一个网页的功能 所以我只是从相应的 nginx
  • 在函数式程序中获取 I/O

    所以我知道你不能在函数式程序中直接从用户那里获取输入 因为它显然不是纯粹的 但如果用户只有 4 个选项可供选择 这仍然适用吗 例如 如果你要求头发颜色 并且有四种选项可供选择 棕色 黑色 金色 红色 那么它是否仍然不纯 如果用户点击与他们的
  • 结合基于多个条件的观察结果

    目前我正在撰写硕士论文 但是 在多个条件下组合行时遇到一些问题 我在下面说明了我的问题和期望的结果 我希望你可以帮助我 这是我的数据集的示例 df lt data frame userID c 1 1 1 1 1 2 2 3 3 3 3 s
  • 什么是流处理中的背压?

    我开始学习 NodeJS 流似乎是人们经常使用的东西 在我读过的大多数文档中都提到了处理大文件时发生的 背压问题 但我还没有找到这个问题到底是什么的明确解释 我还读到使用管道可以帮助解决这个问题 但是管道到底如何解决背压问题呢 感谢您提前的
  • 向自定义验证器添加错误消息

    我有一个自定义验证器 我试图在失败时输出错误消息 但无法这样做 有人可以告诉我我是否在正确的地方执行此操作 class User lt ActiveRecord Base self table name user attr accessib
  • 当给定“const char *”作为第一个参数时,为什么 C 标准库函数“strchr”返回指向非常量的指针?

    使用 gcc g 成功编译给定的代码示例 没有错误strchr调用 这显然分配了const char to char 我发现了strchr被声明为char strchr const char int 在两个不同的来源pubs opengro