【问题标题】:No compiler warning for obvious segfault没有明显的段错误的编译器警告
【发布时间】:2018-02-16 08:53:35
【问题描述】:

我很惊讶这个编译没有任何警告:

int main()
{ 
    *"abc" = '\0';
}

gcc main.c -Wall -Wextraclang main.c -Weverything

为什么没有警告?有什么办法不会引发分段错误?

【问题讨论】:

  • 一个更好的问题是:为什么"abc"[0] = '\0'; 会发出警告?这里的 gcc 似乎有些不一致。
  • 为什么要这样? char * 不是 const 合格的。如果您发现任何语言的编译器都会在代码错误时生成诊断,请申请诺贝尔奖以解决停止问题。并请提供对标准的参考,为什么必须存在段错误或任何其他特定行为。
  • @Olaf 也许我可以反其道而行之,正如 Lundin 所说:如果 char * 不是 const 合格,为什么会有警告 assignment of read-only location"abc"[0] = '\0';
  • 你可能会想出几十个这样的例子,gcc“不会警告”。问题是是否需要。答案是它不是。因为您的代码调用具有未定义的行为。虽然如果 gcc 能识别出这些东西(未定义或未定义)会很好,但对于 所有 此类情况,它通常无法做到。
  • @Bilow: const 并不意味着“只读位置”。字符串文字不是 C 中的 const char []。而且您仍然缺乏证据证明代码需要警告。请注意,我并没有说它是正确的代码,但是没有 C 编译器会警告该语言的所有错误用法。

标签: c gcc segmentation-fault clang gcc-warning


【解决方案1】:

您可以使用-Wwrite-strings 在 GCC 中获取此代码的警告。来自GCC documentation

-Wwrite-strings

编译 C 时,给字符串常量类型 const char[length] 以便将 1 的地址复制到非 const char * 指针中会收到警告。这些警告将帮助您在编译时找到可以尝试写入字符串常量的代码,但前提是您必须非常小心地在声明和原型中使用 const。否则,只会造成麻烦。这就是我们没有发出 -Wall 请求这些警告的原因。

编译 C++ 时,警告从字符串文字到 char * 的不推荐转换。 C++ 程序默认启用此警告。

“有什么方法不会引发分段错误吗?” -> 修改字符串字面量是未定义的行为。所以任何事情都可能发生,包括不发生段错误。

【讨论】:

  • -Wall 和 -Wextra 应该覆盖它
  • 这并不能解释为什么它会警告等效的索引运算符。
  • @savram 不,-Wall 和 -Wextra 不会激活所有可能的警告。
  • @savram:阅读第一次引用的最后一句话!
  • @SamuelPeter:如果我们谈论像 x86 这样的全 OS 系统:不,不是链接器,而是 OS 加载器将 rodata 部分放入写保护的 RAM。如果我们谈论共享库,即动态链接/加载,事情会变得有点复杂。但我会把它留在UB;那是;所有人都需要关心。将段错误和链接器带入游戏确实令人困惑。如果不是真的必要,永远不要改变抽象级别。 UB otoh 是编程和 C 中的一个基本概念。提问者应了解这些基础知识或进行研究。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多