【问题标题】:GCC : Static array index in function argument doesn't trigger any warningGCC:函数参数中的静态数组索引不会触发任何警告
【发布时间】:2018-12-28 14:11:23
【问题描述】:

我试图理解“static”关键字在 C 中的函数声明中作为数组索引的使用。

阅读this article后,我尝试声明这样一个函数,并故意将一个太短的数组传递给它:

#include <stdio.h>
#include <stdlib.h>


void print_string10(char string10[static 10]) {

// Should trigger a warning if the argument is NULL or an array of less than 10 elements

    printf("%s\n",string10);

}

int main(void) {

    char short_string[] = "test";

    print_string10(short_string); // should trigger a warning as the string is 5 long

    return EXIT_SUCCESS;
}

如文章中使用clang 编译会触发警告,但gcc -Wall -Werror 不会,它编译并运行良好。

我找不到解释,GCC 忽略此警告是正常行为吗?

【问题讨论】:

  • 你有 GCC 的哪个版本?您在构建时是否传递了任何其他选项或标志?
  • 似乎不需要任何消息。编译器可以忽略那里的关键字。
  • 我使用的是 gcc 6.3.0,只有-Wall -Werror

标签: c gcc clang gcc-warning


【解决方案1】:

为什么它不需要触发警告是因为它发生的标准部分 - 6.7.6.3p7:

语义

[...]

  1. 将参数声明为“类型数组”应调整为“类型限定指针”,其中类型限定符(如果有)是在数组类型派生的 [ 和 ] 中指定的限定符.如果关键字 static 也出现在数组类型派生的 [ 和 ] 中,那么对于函数的每次调用,对应的实际参数的值提供对数组第一个元素的访问至少与 size 表达式指定的元素一样多。

它出现在语义部分。只有在诊断出现在约束中的那些时,才需要一个符合要求的实现。即使它没有在此处诊断违规,它也可以使用static 关键字的知识来推断参数不为空,并且循环展开和其他优化可能期望一个至少具有那么多元素的数组。


还要注意,那里的example 5 是这么说的

   void   f(double      (* restrict a)[5]);
   void   f(double      a[restrict][5]);
   void   f(double      a[restrict 3][5]);
   void   f(double      a[restrict static 3][5]);

都是兼容的,即您可以在函数指针分配中混合和匹配它们而无需强制转换,即使一个具有static 维度!

如果调用是通过函数指针实现的,clang(也许是正确的)似乎失去了诊断任何东西的能力:

void (*f)(double a[restrict static 3]);

int main(void) {
    double a[1] = {0};
    f(a);
}

(在 Clang 7.0 中没有诊断 - 删除 * 你会得到它们)。

【讨论】:

  • 感谢您的详细回答。在 dbush 提供的 gcc bug tracker 的链接中,有人说:“我不推荐这种静态关键字的用法。甚至有可能删除/弃用此功能。[...]”同意这个吗?应该改用什么?
  • @SuperBoby DR205 抱怨static 关键字的使用,并不是说该功能不好。它存在于 99、11 和 17 修订版中,它不会很快消失,因此 GCC现在应该最大程度地支持它而不是只提供替代机制。
  • @SuperBoby 此外,使用static 的问题在于它在函数参数中起作用,而其他一些机制可能在需要指针的任何地方都起作用跨度>
  • 在其他什么情况下,您需要像这样限制数组大小?
【解决方案2】:

看起来这是 GCC 中的一个错误。关于是否应该在编译时报告,似乎存在一些分歧。尽管如此,它被认为是一个错误,但似乎没有优先修复它。

这在错误报告50584 中有详细说明。评论 9 特别指出:

(从评论 #4 中回复 Malcolm Inglis)

有人可以更改此错误的状态吗?

无论该功能是漂亮还是丑陋,GCC 都接受 如果可能,此代码和未定义行为的警告是 想要的。至此,得到证实。

这并不意味着任何人都会努力解决这个问题。请,如果 您正在使用此功能并希望在 GCC 中看到此警告, 请考虑贡献它: https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps

如果你开始研究这个,最好在这里说出来。

【讨论】:

  • 我们应该注意到这是一个错误,因为 GCC 不符合其维护者/贡献者/请求者所期望的行为,而不是因为 GCC 不符合 C 标准。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 2011-03-27
  • 2021-11-22
相关资源
最近更新 更多