Я получаю несколько странных предупреждений об этом коде:
typedef double mat4[4][4];
void mprod4(mat4 r, const mat4 a, const mat4 b)
{
/* yes, function is empty */
}
int main()
{
mat4 mr, ma, mb;
mprod4(mr, ma, mb);
}
gcc
выводит следующее:
$ gcc -o test test.c
test.c: In function 'main':
test.c:13: warning: passing argument 2 of 'mprod4' from incompatible pointer
type
test.c:4: note: expected 'const double (*)[4]' but argument is of type 'double
(*)[4]'
test.c:13: warning: passing argument 3 of 'mprod4' from incompatible pointer
type
test.c:4:
note: expected 'const double (*)[4]' but argument is of type 'double
(*)[4]'
Если я определяю функцию как:
void mprod4(mat4 r, mat4 a, mat4 b)
{
}
Или определяю матрицы в основном как:
mat4 mr;
const mat4 ma;
const mat4 mb;
Или вызовите функцию в main как:
mprod4(mr, (const double(*)[4])ma, (const double(*)[4])mb);
Или даже определив mat4
как:
typedef double mat4[16];
Удаляет предупреждение. Что здесь происходит? Я делаю что-то недопустимое?
Версия gcc - 4.4.3, если уместно.
Я также написал на gcc bugzilla: http://gcc.gnu.org/bugzilla/show_bug.cgi?id = 47143
Мой текущий обходной путь - создание уродливых макросов, которые меняют содержимое:
#ifndef _NO_UGLY_MATRIX_MACROS
#define mprod4(r, a, b) mprod4(r, (const double(*)[4])a, (const double(*)[4])b)
#endif
Ответ Джозефа С. Майерса на gcc bugzilla:
Это не ошибка. Параметры функции имеют тип "указатель на массив [4] из const double "потому что const на тип массива применяется к элементу рекурсивно, а затем только самый внешний тип массива параметр типа массива распадается на указатель, и переданные аргументы типа "указатель на массив [4] из double "после распада массива на указатель, и единственный случай, когда квалификаторы разрешено добавлять в задание, передача аргументов и т. д. - это квалификаторы непосредственная цель указателя, а не те, которые вложены более глубоко.
Звучит довольно запутанно, как и ожидает функция:
pointer to array[4] of const doubles
и мы передаем
pointer to const array[4] of doubles
intead.
Или это будет наоборот? Предупреждения предполагают, что функция ожидает:
const double (*)[4]
, который мне кажется больше похожим на
pointer to const array[4] of doubles
. Я действительно смущен этим ответом. Может ли кто-нибудь, кто понимает то, что он сказал, прояснить и проиллюстрировать?