2015-07-11 4 views
1

Я пытаюсь вызвать функцию c с аргументом const matrix, используя const const, но не могу найти синтаксис, который останавливает жалобу gcc-компилятора. Код ниже компилируется без жалобы, если удаляются все «const». Вопрос похож на C function const multidimensional-array argument strange warning, но здесь не было удовлетворительного решения. В следующем коде, если первый вызов функции g() работает, тогда второй вызов g() должен также работать, так как он синтаксически идентичен. Но это не так. Вторая версия g() предпочтительна, поскольку она не требует заранее знать тип матрицы.Вызвать функцию c аргументом const-матрицы, используя const const

/* file t.c */ 
void f(const int a[2]) {/*empty*/} 
void g(const int b[2][2]) {/*empty*/} 

int main() 
{ 
    int a[2]; 
    int b[2][2]; 

    f((const int (*)) a);     /* ok */ 
    f((const typeof(&a[0])) a);    /* ok */ 
    g((const int (*)[2]) b);    /* ok */ 
    g((const typeof(&b[0])) b);    /* compiler complains */ 
} 

$ gcc -o t t.c 
t.c: In function ‘main’: 
t.c:13:2: warning: passing argument 1 of ‘g’ from incompatible pointer type [enabled by default] 
    g((const typeof(&b[0])) b); /* compiler complains */ 
^
t.c:3:10: note: expected ‘const int (*)[2]’ but argument is of type ‘int (*)[2]’ 
    void g(const int b[2][2]) {/*empty*/} 
+1

'Const TypeOf (& Ь [0])' является 'INT (* Const) [2]', а не 'сопзЬ Int (*) [2]', то есть указатель сам по себе является Const, а не элементы , –

+1

Приведение не делает ничего полезного. Вы можете просто вызвать функции как 'f (a)' и 'g (b)'. – user3386109

+0

Да, можно просто назвать функции как f (a) и g (b), и все работает. Проблема заключается в том, что компилятор жалуется. У меня есть большой код, который вызывает библиотечные функции с аргументами const. gcc помещает компиляцию с жалобами, которых не должно быть. – ajsh

ответ

-1

Элемент const в заголовке объявления означает, что функция не может изменить содержимое аргумента. Это информация для вызывающего (компилятора) и программиста. Таким образом, нет причин для создания типа const, а затем вызова функции. Это совершенно излишне.

+1

Было бы излишним, если бы не ошибка компилятора. http://ideone.com/Oow2hn – rici

+0

Я не знал, компилятор сделал это. Очень странное поведение. –

2

Да, это отсутствие возможности вызвать функцию с помощью const 2D-массивы с аргументом const - это действительно дефект в спецификации C.

Для перемещения по ней помнить, что

void g(const int b[2][2]) {/*empty*/} 

переписывается в

void g(const int (*b)[2]) {/*empty*/} 

так что это показывает вам, как вы должны преобразовать, в const int (*)[2], то есть указатель на массив от 2 double.

g((const int (*)[2])b); 
+0

Сообщение об ошибке gcc также полезно при запоминании того, как писать тип: 'expected 'const int (*) [2]', но аргумент имеет тип 'int (*) [2]'' – rici

+0

Все это правильно. Проблема в том, что int (*) [2]) b должен быть таким же, как typeof (& b [0]) (я думаю), но компилятор не признает их одинаковыми. – ajsh

+0

@ajsh, нет, он должен быть таким же, как 'typeof (& b)' без '[0]'. –