【问题标题】:GCC vs Clang: Meaning of "-pedantic-errors"GCC vs Clang:“-pedantic-errors”的含义
【发布时间】:2016-12-13 17:02:15
【问题描述】:

我在 Windows 10 上使用带有 Mingw-w64 5.1.0 和 GCC 5.1.0 的 Clang v3.7.0,全部为 64 位。我的目标是使用一组 Clang 和 GCC 选项,这将为我提供在许多不同的编译器中检测潜在的C89C++98 语言标准可移植性问题的最佳机会。例如,对于 C,我一直在使用以下 GCC 命令行并取得了相当大的成功:

gcc -c -x c -std=c89 -pedantic-errors -Wall -Wextra -Wno-comment -Wno-parentheses -Wno-format-zero-length test.c

但是,我最近使用 Clang 进行了尝试,得到了不同的结果。这是我的示例测试代码:

int main(void)
{
    int length = (int)strlen("Hello");
    return 0;
}

使用 Clang 我得到以下错误,而使用 GCC 我得到相同的基本内容,但它会将其标记为警告:

test.c:3:22: error: implicitly declaring library function 'strlen'
with type 'unsigned long long (const char *)'
    int length = (int)strlen("Hello");

如果我删除 -pedantic-errors 选项,或者只是将其更改为 -pedantic,那么 Clang 只会将其标记为警告,这正是我真正想要的.但是,根据 GCC 文档,-pedantic-errors 选项会导致将被视为语言扩展的警告标记为错误,但不使用函数原型不是 C89 中的扩展。所以,我有三个基本问题:

  1. Clang 是否将 -pedantic-errors 的含义与 GCC 使用的含义不同,还是我误解了什么?

  2. 强制遵守所选标准并对所有不合格代码发出错误的最佳选项是什么?

  3. 如果我继续将 -pedantic-errors 与 Clang 一起使用,是否有办法让它在特定情况下发出警告而不是错误?在该站点上的另一篇帖子中,给出了一个答案,据说使用以下内容,其中 foo 是错误:

    -Wno-error=foo
    

如果这是一个正确的方法,我应该用什么来代替 foo 来解决我遇到的错误,因为没有指示实际的错误编号?我不敢相信它实际上想要以下所有内容:

-Wno-error=implicitly declaring library function 'strlen'
with type 'unsigned long long (const char *)'

【问题讨论】:

  • 哦,你真的不应该使用 C89。它已经过时了 17 年,并且与标准 C 不完全兼容。对于 C++98 类似。 C++11 有了很大的改进。
  • @Olaf:C 标准的早期版本并没有在后来的版本发布时神奇地消失。它们仍然存在,gcc 仍然支持它们。请注意,当前的 C++ 标准在规范性文本中仍然引用您声称不存在的 C99 标准。我相信 POSIX 也是如此。
  • @Olaf:请不要再粗鲁了。
  • @Olaf:IEEE 与 C 或 C++ 标准无关;两者均由 ISO 发布。 ISO 已声明该标准的先前版本已过时。该声明在什么意义上对其他人具有约束力? 允许选择使用旧版语言标准的人这样做。同样,现有的现行标准(其中一些由 ISO 发布)在规范上依赖于旧版本的 C 标准。
  • @Olaf 在一个旨在帮助他人解决问题的网站上,似乎很简单的问题变成了关于语义的论文,这对我来说似乎很奇怪。如果我只是说“C89 和 C++98 语言版本”而不是“C89 和 C++98 语言标准”,是否可以避免所有这些?我只是不明白为什么有些人会挑剔这样的事情,而不是简单地看到明显的意图。我也知道旧的“版本”(不是标准)已经过时,但程序员可能不得不遵守它们的原因有很多。

标签: c++ c gcc clang portability


【解决方案1】:

您的代码无效,并且行为未定义,因此编译器可以执行任何操作also when compiling。隐式声明的int strlen(char*)size_t strlen(const char *) 不兼容。

Clang 是否将 -pedantic-errors 的含义与 GCC 使用的含义不同,还是我误解了什么?

当我读到它时,是的。来自 clang 文档:

-pedantic-errors

    Error on language extensions.

在 GCC 中:

-pedantic

    Issue all the warnings demanded by strict ISO C and ISO C++ [...]

-pedantic-errors

    Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard.

扩展上的 Clang 错误。

当标准明确要求和其他“某些情况”时出现 GCC 错误。

这是不同的,它是一组不同的错误。标准可能不需要诊断,但它仍然是扩展 - GCC 将保持沉默,Clang 将出错。

强制遵守所选标准并对所有不合格代码发出错误的最佳选项是什么?

想到的第一个答案是:“无”。编译器本质上使用“实现定义的行为”和扩展,因为它们首先是为了编译代码,而不是为了不编译不合格的代码。在某些情况下代码符合要求,但编译器之间的行为仍然不同 - 您可以探索此类 a case here

无论如何,请继续使用-pedantic-errors,因为它似乎可以检测不合格代码。您的代码无效,行为未定义,因此您的代码不符合要求,因此 clang 可以正确检测到它。还可以使用 linter 和 sanitizer 来检测其他未定义行为的情况。

如果我继续在 Clang 中使用 -pedantic-errors,有没有办法让它在特定情况下发出警告而不是错误?

使用-fno-builtin

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-21
    • 2011-08-30
    • 2020-11-07
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    相关资源
    最近更新 更多