我对这个没有任何警告就编译通过感到惊讶:
int main()
{
*"abc" = '\0';
}
使用
gcc main.c -Wall -Wextra
和 clang main.c -Weverything
命令时,为什么没有任何警告?这段代码有可能不会导致分段错误吗?我对这个没有任何警告就编译通过感到惊讶:
int main()
{
*"abc" = '\0';
}
gcc main.c -Wall -Wextra
和 clang main.c -Weverything
命令时,为什么没有任何警告?这段代码有可能不会导致分段错误吗?-Wwrite-strings
在GCC中获取此代码的警告。从GCC文档中了解到:
-Wwrite-strings
编译C语言时,将字符串常量的类型设置为const char[length],这样将其地址复制到非const char *指针中会得到一个警告。如果您在声明和原型中非常小心地使用const,则这些警告将帮助您在编译时找到可能尝试写入字符串常量的代码。否则,它只是一种麻烦。这就是为什么我们没有让-Wall请求这些警告。
编译C ++时,警告已停用从字符串字面值到char *的转换。对于C ++程序,默认情况下启用此警告。
"是否有任何方法不引发段错误?" -> 修改字符串文字是未定义行为。因此,任何事情都可能发生,包括不会导致段错误。
rodata
部分放置到写保护RAM中。如果我们谈论共享库,即动态链接/加载,事情会变得更加复杂。但我只会把它留在UB上;那就是所有人需要关心的。把段错误和链接器引入游戏中确实令人困惑。除非真正必要,否则永远不要改变抽象级别。另一方面,UB是编程和C特别是基本概念。提问者应该理解这些基础知识或进行研究。 - too honest for this site
"abc"[0] = '\0';
会有警告?这似乎是gcc中的一些不一致。 - Lundinchar *
没有被const
限定。如果你找到了一种语言的编译器,可以在代码错误时生成诊断信息,请申请解决停机问题的诺贝尔奖。并且,请提供标准的参考,解释为什么必须有分段错误或任何其他特定的行为。 - too honest for this sitechar *
没有被const
限定,为什么使用"abc"[0] = '\0';
会出现警告assignment of read-only location
? - Bilow*(“ABC”+ 0)= '\0';
也不会发出警告。那将是索引运算符的确切等效物。 - too honest for this site