Я прочитал эту тему и искал дополнительную информацию, но большинство людей просто говорят: "Не используйте typedefs, как это". Этот способ работы мне нравится, и я также пытаюсь изучать новые вещи, поэтому я хочу придерживаться этого.
Я использую gcc версии 9.2.1
Вотминимальный воспроизводимый пример того, что я делаю:
#define TABLE_SZ 10
typedef int vec_t[3];
typedef struct {
vec_t table_one[TABLE_SZ];
} tables;
void foo(vec_t * foo_vec) {
(*foo_vec)[0] = 0;
}
void bar (tables bar_table, vec_t bar_vec) {
foo(&(bar_table.table_one[0]));
foo(&bar_vec);
}
int main() {
vec_t vector;
foo(&vector);
}
/home/happy/CLionProjects/os_2019_p5/tests/test_array_typedef_ops.c: In function ‘bar’:
/home/happy/CLionProjects/os_2019_p5/tests/test_array_typedef_ops.c:18:7: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
18 | foo(&bar_vec);
| ^~~~~~~~
| |
| int **
/home/happy/CLionProjects/os_2019_p5/tests/test_array_typedef_ops.c:12:18: note: expected ‘int (*)[3]’ but argument is of type ‘int **’
12 | void foo(vec_t * foo_vec) {
| ~~~~~~~~^~~~~~~
Я предполагаю, что это как-то связано с "затуханием указателя", я думаю, бар преобразует bar_vec в int **? В частности, почему тип & (bar_table.table_one [0]) int (*) [3], когда bar_vec имеет тип int **?
Я явно не хочу подавлять все предупреждения о несовместимых типах указателей вgcc.
Приведение указателя кажется клуджем. Я хочу сохранить typedef. Я не хочу скрывать это в структуре.
Есть ли флаг компилятора или другое решение, чтобы сказать компилятору, чтобы я воспринимал эту ситуацию так, как я ожидаю? Есть ли еще информация по этому вопросу, о которой я должен знать?
Спасибо.
ps имеет ли переполнение стека красивую печать для вывода компилятора?