c - GCC:函数参数中的静态数组索引不会触发任何警告
问题描述
我试图了解在 C 中的函数声明中使用“静态”关键字作为数组索引。
读完这篇文章后,我尝试声明这样一个函数,并有目的地传递一个太短的数组:
#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;
}
使用文章中的 as 进行编译clang
会触发警告,但gcc -Wall -Werror
不会,它编译并运行良好。
我找不到解释,GCC 忽略这个警告是正常行为吗?
解决方案
为什么它不需要触发警告是因为它发生的标准部分 - 6.7.6.3p7:
语义
[...]
- 将参数声明为“类型数组”应调整为“类型限定指针”,其中类型限定符(如果有)是在数组类型派生的 [ 和 ] 中指定的那些。如果关键字 static 也出现在数组类型派生的 [ 和 ] 中,则对于函数的每次调用,对应的实际参数的值应提供对至少与指定元素一样多的数组的第一个元素的访问由大小表达式。
它出现在语义部分。只需要一个符合要求的实现来诊断那些出现在约束中的实现。即使它没有在此处诊断违规,它也可以使用static
关键字的知识来推断参数不为空,并且循环展开和其他优化可能期望一个至少具有那么多元素的数组。
还要注意,那里的示例 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 中没有诊断 - 删除*
,你会得到它们)。
推荐阅读
- powershell - 如何使用调用运算符将参数传递给另一个 PowerShell 脚本
- python - 如何在 django 应用程序中的模板中创建
- terraform - Terraform 目录“.terraform/modules”命名约定
- math - 如何在给定度量和已知范围 [m,M] 映射到 4 的情况下计算分数 0-4?
- java - 直接绘制到画布并使用 java 代码创建布局
- function - 球拍:预期:程序?
- amazon-web-services - 使用 Terraform 管理 IAM 代入角色创建
- javascript - Trying to make different HTML paragraph show depending on selection
- javascript - 在 FullCalendar 的月时间线视图中显示中午的事件
- r - 这是潜在的代码错误还是机器设置错误?没有把握