考虑一下这个C代码:
#include <stdio.h>
static void print_matrix(size_t rows, size_t cols, const int data[rows][cols])
{
for (size_t r = 0; r < rows; r++)
{
const char *pad = "";
for (size_t c = 0; c < cols; c++)
{
printf("%s%3d", pad, data[r][c]);
pad = " ";
}
putchar('\n');
}
}
int main(void)
{
/* Created by: gen_matrix -r 3 -c 5 -L 0 -H 999 -n matrix -E -w 3 -S 0x08C777A9 -i */
/* Random seed: 0x08C777A9 */
int matrix[3][5] =
{
{ 984, 843, 464, 599, 17, },
{ 876, 173, 647, 61, 387, },
{ 138, 245, 718, 981, 629, },
};
enum { MATRIX_ROWS = 3, MATRIX_COLS = 5 };
print_matrix(MATRIX_ROWS, MATRIX_COLS, matrix);
return 0;
}这是我使用的makefile:
# Makefile to demonstrate inconsistency between GCC 11.2.0 and Apple Clang 13.0.0.
CC = gcc
OFLAGS = -O3
GFLAGS = -g
WFLAG1 = -Werror
WFLAG2 = -Wall
WFLAG3 = -Wextra
WFLAG4 = -pedantic
WFLAG5 = -pedantic-errors
UFLAGS = # Set on command line
WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5}
CFLAGS = ${OFLAGS} ${GFLAGS} ${WFLAGS} ${UFLAGS}
PROG1 = gcc23
FILE.c = ${PROG1}.c
PROGRAMS = ${PROG1}
all: ${PROGRAMS}
${PROG1}:
${CC} ${CFLAGS} ${FILE.c} -o $@我有两个编译器:
$ gcc --version
gcc (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang --version
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$请考虑以下构建记录:
$ rm -f gcc23
$ make CC=gcc
gcc -O3 -g -Werror -Wall -Wextra -pedantic -pedantic-errors gcc23.c -o gcc23
gcc23.c: In function ‘main’:
gcc23.c:29:44: error: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]
29 | print_matrix(MATRIX_ROWS, MATRIX_COLS, matrix);
| ^~~~~~
make: *** [gcc23] Error 1
$ rm -f gcc23
$ make CC=clang
clang -O3 -g -Werror -Wall -Wextra -pedantic -pedantic-errors gcc23.c -o gcc23
$ rm -f gcc23
$ make CC=clang UFLAGS=-Weverything
clang -O3 -g -Werror -Wall -Wextra -pedantic -pedantic-errors -Weverything gcc23.c -o gcc23
error: include location '/usr/local/include' is unsafe for cross-compilation [-Werror,-Wpoison-system-directories]
gcc23.c:3:73: error: variable length array used [-Werror,-Wvla]
static void print_matrix(size_t rows, size_t cols, const int data[rows][cols])
^~~~
gcc23.c:3:67: error: variable length array used [-Werror,-Wvla]
static void print_matrix(size_t rows, size_t cols, const int data[rows][cols])
^~~~
3 errors generated.
make: *** [gcc23] Error 1
$添加-std=c99、-std=c11或-std=c18不会更改编译错误。使用Clang的-Weverything选项编译的错误与函数参数上的const限定符无关。添加-Wno-vla意味着代码在Clang下干净地编译(并且-Werror,-Wpoison-system-directories错误也消失了)。
正如您所看到的,GCC抱怨在函数的参数中添加了const,但是Clang没有。
我希望这是克莱昂,这是正确的-这符合我的期望。
发布于 2022-08-15 05:45:05
是正确的,
Gcc。
为什么?
来自https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1923.htm:
在当前的C标准中,限定符总是附加到数组的元素类型。不可能声明为const的数组类型:
6.7.3(9):如果数组类型的规范包括任何类型限定符,则元素类型是如此限定的,而不是数组类型。该标准有一个显式规则,它允许指针的转换将限定符添加到目标类型。
6.3.2.3(3):对于任何限定符q,指向非q限定类型的指针可以转换为指向该类型的q限定版本的指针;原始指针和转换指针中存储的值应比较相等。如果目标是数组,则第二条规则不适用,因为限定符位于元素类型上,而不是数组本身。这会在使用指向数组的指针时引起实际问题。
在C2X https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.pdf中,我在6.7.3(10)中看到:
10如果数组类型的规范包括任何类型限定符,数组和元素类型都是如此限定的。.
https://stackoverflow.com/questions/73356925
复制相似问题