Теперь я получаю предупреждение даже за первый аргумент LOL. И мне нужно, чтобы он был mat4, чтобы я мог написать [i] [j] для индексирования, а не [i * 4 + j], что немного раздражает.
учаю некоторые странные предупреждения об этом коде:
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] двойного» после распада массива на указатель, и единственный случай, когда разрешено добавление квалификаторов при присваивании, передаче аргумента и т. д., - это квалификаторы по непосредственному указателю цель, а не те, которые вложены глубже.
Звучит довольно странно для меня, как ожидает функция:
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
Я действительно запутался с этим ответом. Может ли кто-то, кто понимает, что он сказал, уточнить и привести пример?