-Wc++-compat 产生的有关尚未由宏扩展的标识符的警告是否误报?

问题描述 投票:0回答:1

我一直在针对一些非常“非默认”的警告编译我的 C 代码,并发现了一个潜在的 GCC 错误 - 由

-Wc++-compat
引起的误报。 在解释任何内容之前,先介绍一下代码可能会更容易:

main.c

#include <stdio.h>

#define X_KEYWORDS  \
        X(bool)     \
        X(not)      \
        X(and)      \
        X(or)       \
        X(xor)      \
        X(nullptr)  \
        X(true)     \
        X(false)

int main(void)
{
#       define X(keyword) puts(#keyword);
        X_KEYWORDS
#       undef X
        return 0;
}

当使用

-Wc++-compat
编译时,GCC 会打印以下诊断信息:

$ gcc main.c -Wc++-compat
main.c:5:11: warning: identifier "not" is a special operator name in C++ [-Wc++-compat]
    5 |         X(not)      \
      |           ^
main.c:6:11: warning: identifier "and" is a special operator name in C++ [-Wc++-compat]
    6 |         X(and)      \
      |           ^
main.c:7:11: warning: identifier "or" is a special operator name in C++ [-Wc++-compat]
    7 |         X(or)       \
      |           ^
main.c:8:11: warning: identifier "xor" is a special operator name in C++ [-Wc++-compat]
    8 |         X(xor)      \
      |

如您所见,它警告我有关宏定义内部的构造;这些还没有在任何地方扩展。

main
的主体在这里无关紧要;它甚至可以是空的 -
int main(void) {}
- 并且无论如何都会出现相同的警告。我只是想证明这个特定的 X-Macro 有一个有效的用例。

这些警告永远不会出现在实际的扩展代码中。我的代码片段将它们扩展为对我来说有效的字符串文字。我不明白它如何违反 C++ 方言。

那些“错误”的标识符与 libc 中定义的标识符相同

<iso646.h>
(?)。 请注意,我还在宏体内使用了其他特定于 C++ 的关键字,例如
bool
nullptr
,并且警告并未指向它们。

无论如何,上述行为似乎不会发生在 clang 中:

$ clang main.c -Wc++-compat

并且可以像 C++ 一样使用我目前可用的所有编译器进行编译:

$ mv main.c main.cpp
$ g++ main.cpp
$ cl main.cpp /nologo
main.cpp
$ clang++ main.cpp

  • 我可以安全地假设这是一个 GCC 特定的错误吗?
  • 或者在任何情况下这些诊断都是有效的吗?
  • 为什么它只警告来自
    <iso646.h>
    的内容?

(参考资料)

$ uname -a
Linux MAL200424 6.11.6-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 01 Nov 2024 03:30:41 +0000 x86_64 GNU/Linux

$ gcc --version
gcc (GCC) 14.2.1 20240910

$ clang --version
clang version 18.1.8

godbolt 链接:https://godbolt.org/z/8jo363EbP
GCC 手册:https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Warning-Options.html#index-Wc_002b_002b-compat
关于https://en.cppreference.com/w/c/language/operator_alternative

c++ c gcc warnings gcc-warning
1个回答
0
投票
  • 我可以安全地假设这是一个 GCC 特定的错误吗?

正如您自己观察的那样,诊断标记了宏

X_KEYWORDS
的定义,而不是它扩展的位置。 此时,编译器不知道如何使用该宏,因此最好将该行为描述为 GCC 非常谨慎,而不是有错误。 我认为它是在告诉您,可能有一些方法可以使用与 C++ 不兼容的宏。 如果您确实以这种方式使用它,我预计您会得到额外的诊断。

所以不,你不应该认为诊断有问题,但你也不应该认为它们表明你的整个程序不是有效的 C++。

  • 或者在任何情况下这些诊断都是有效的吗?

见上文。

  • 为什么它只警告来自 的内容?

在考虑的特定预处理标记中,GCC 警告的标记在 C++ 中属于

preprocessing-op-or-punc
类型,而在 C 中属于
identifier
类型。其他标记在两种语言中都属于
identifier
类型。 这似乎就是 GCC 将前一组中的人员称为“特殊操作员名称”的意思。 这也是潜在不兼容的基础。

© www.soinside.com 2019 - 2024. All rights reserved.