Я получаю некоторые странные предупреждения об этом коде:
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)
{
}
Или определение матриц в main как:
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
Я действительно смущен этим ответом. Может ли кто-то, кто понимает, что он сказал, уточнить и привести пример?