【问题标题】:clang: <string literal> + <expression returning int> leads to confusing warning: adding 'int' to a string does not append to the stringclang: <string literal> + <expression returned int> 导致令人困惑的警告:将 'int' 添加到字符串不会附加到字符串
【发布时间】:2021-10-13 08:27:27
【问题描述】:

这段代码:

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
  bool flag = true;
  printf("%s\n", "xxxzzz" + ( flag ? 3 : 0 ));
  return 0;
}

使用-std=c11 -pedantic 编译会导致警告:

main.c:7:27: warning: adding 'int' to a string does not append to the string
      [-Wstring-plus-int]
  printf("%s\n", "xxxzzz" + ( flag ? 3 : 0 ));
                 ~~~~~~~~~^~~~~~~~~~~~~~~~~~
main.c:7:27: note: use array indexing to silence this warning
  printf("%s\n", "xxxzzz" + ( flag ? 3 : 0 ));
                          ^
                 &        [                 ]
1 warning generated.

但是,这段代码:

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
  bool flag = true;
  printf("%s\n", ("xxxzzz") + ( flag ? 3 : 0 ));
  return 0;
}

使用-std=c11 -pedantic 编译不会导致警告。

为什么会出现这个警告?

为什么() 很重要?

附: gcc / msvc 在这两种情况下都不会产生警告。

【问题讨论】:

  • 这是一个特定的编译器内部问题,而不是语言。我推测括号以某种方式暗示编译器您知道自己在做什么。有不同的方法可以消除编译器警告,这是特定编译器的其中一种。
  • @EdHeal &amp;"xxxzzz" [flag ? 3 : 0 ] 实际上
  • @EdHeal:同意,尤其是。因为该消息包括note: use array indexing to silence this warning
  • 一种猜测是,在内部,表达式"xxxzzz"AST 节点带有一个标签,上面写着“这是一个字符串文字”,并且当带有该表达式的表达式时,编译器会生成一个警告标签显示为+ 的一个操作数。但是该标签可能不会向上传播,因此表达式("xxxzzz") 可能不会从其子表达式"xxxzzz" 中“继承”该标签,因此当您将其与+ 一起使用时不会发出警告。
  • 您说警告“令人困惑”,但希望您能理解其意图:来自 Javascript 等语言的初学者可能会期望 + 可用于连接字符串,并且像这样的对象一个整数将被转换为一个字符串,然后连接起来。所以他们可能认为"xxxzzz" + 3 会产生字符串"xxxzzz3"。该警告是针对那些初学者的,仅此而已。

标签: c clang compiler-warnings c11


【解决方案1】:

警告仅仅是因为代码不习惯(即指针算法的不寻常使用),来自其他语言的人可能期望 RHS 的自动字符串转换来创建 "xxxzzz3""xxxzzz0"

这是编译器发现代码模式可能在其他语言中很常见,但在 C 中具有不同且可能意外的语义。它试图提供帮助并防止常见错误。

在任何情况下,就清晰的语义而言,使用数组索引语义的建议可能是更好的解决方案,但使用括号显然具有抑制警告的相同效果。

【讨论】:

  • 类似于if ( x = 3 ) 之类的警告,您可以通过写if ( (x = 3) ) 来表示“是的,我知道我正在使用=而不是=="。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
相关资源
最近更新 更多