【问题标题】:Is comparing the same string literals always true? [duplicate]比较相同的字符串文字总是正确的吗? [复制]
【发布时间】:2023-03-18 02:51:01
【问题描述】:

在 C 语言中,编译器/链接器是否有义务将多次使用的相同字符串文字放入单个内存位置?

const char* a = "abcdef";
const char* b = "abcdef";

//Compare pointers
if (a == b) {
    printf("True\r\n");
} else {
    printf("False\r\n");
}

在这种情况下,上面的陈述总是正确的(在 MSVC 2017 中是)还是一般未定义的行为

我们在2 不同的内存位置有字符串文字abcdef 会发生吗?当然,我不计算像12abcdefgh˛这样的字符串,其中abcdef 是字符串的一部分,而是独立的。

【问题讨论】:

  • 这取决于编译器选项。是否合并重复定义。
  • 我认为 undefined behavior 在这里用词不当。该程序的行为被很好地定义为它将打印“True”或“False”(与段错误相反,格式化您的硬盘驱动器等)
  • 实现的行为,显然不要在你的程序中假设。
  • 比较不指向(或完全过去)同一数组的指针是未定义的行为。
  • 不,编译器不需要将字符串文字的多个实例映射到同一位置。见N1570,6.4.5/7。

标签: c string


【解决方案1】:

您在这里比较的是 指针 到字符串文字。字符串文字被静态分配在一些不应该被写入的内存中。优化编译器可能只分配一次相同的字符串文字,因为它假设这些文字永远不会改变,并且拥有多个副本没有意义,这就是您在这里观察到的。但不能保证。

【讨论】:

  • 它还可以执行其他转换来删除字符串文字内容。例如,"hello world"+6 == "world" 可能为真。
  • @R.. 那是我从未见过的东西.. (也许是因为从未检查过:))
  • 要清楚,@R.. 的注释不是字符串比较,而是指针比较。
  • @WeatherVane:C 中没有“字符串比较”之类的东西,除非你的意思是strcmp,当然strcmp("hello world"+6, "world")==0 总是正确的。
  • @R.. 显然,这就是我认为 you 的意思。我在放大你真实但不清楚的评论。
【解决方案2】:

这是未指定的行为,但大多数编译器会对此进行优化,使其成为真的。如果您正在对特定编译器进行编码,您可能会找到一个开关或 #pragma 来控制此类字符串的折叠,从而为您提供确定性。

【讨论】:

  • “未定义的行为”是错误的术语;我想这里的行为是“实现定义”
  • @StephanLechner 只要我们在吹毛求疵,它实际上就是“未指定的行为”。见附件 J.1 和第 6.4.5 节。
  • 是否可以保证代码中使用的任何 特定 字符串文字(在宏扩展之后)将始终具有常量地址,例如给定inline char const *foo(void) { return "Hey";},在翻译单元内每次调用foo 都会产生相同的地址?
  • 是的,字符串字面量是数组的常量地址,其中包含后跟 NUL 终止符的字符
猜你喜欢
  • 2021-11-28
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 2022-11-07
相关资源
最近更新 更多