una por pasar parametro multiplicacion matriz matrices llenar funciones funcion con como bidimensional arreglo array c arrays pointers gcc-warning

por - Pase una matriz bidimensional a una función de parámetro constante



pasar un arreglo como parametro en java (2)

Aprendí de C Primer Plus que si desea proteger una matriz de ser modificada accidentalmente por una función, debe agregar un modificador const antes de la declaración del puntero en el encabezado de la definición de la función.

Siguiendo este consejo sensato, en el siguiente ejemplo mínimo, estoy tratando de pasar una matriz de array bidimensional no constante a la función Sum2D , Sum2D parámetro es un pointer-to-const-int[2] .

#include <stdio.h> #define ROWS 2 #define COLS 2 int Sum2D(const int ar[][COLS], int rows); //use `const` to protect input array int main(void) { int array[ROWS][COLS]={{1,2},{3,4}}; //the non-constant array printf( "%d/n", Sum2D(array,ROWS) ); return 0; } int Sum2D(const int ar[][COLS], int rows) { int total=0; int i,j; for( i=0 ; i<rows ; i++ ) { for( j=0 ; j<COLS ; j++ ) { total+=ar[i][j]; } } return total; }

Sin embargo, gcc no puede compilar con éxito este código sin emitir las siguientes advertencias:

$gcc -ggdb3 -Wall -Wextra -o test test.c test.c: In function ‘main’: test.c:16:2: warning: passing argument 1 of ‘Sum2D’ from incompatible pointer type [enabled by default] printf( "%d/n", Sum2D(array,4) ); ^ test.c:4:5: note: expected ‘const int (*)[4]’ but argument is of type ‘int (*)[4]’ int Sum2D(const int ar[][COLS], int rows); ^

1) ¿Por qué la advertencia?

2) ¿Cómo puedo eliminar el "ruido"? (Además de agregar const a la declaración de array ).

(Si la array y la función utilizan una matriz unidimensional, no hay advertencia).

Información del sistema:

Ubuntu 14.04LTS

Compilador: gcc 4.8.2


Este es un desafortunado "error" en el diseño de C; T (*p)[N] no se convierte implícitamente en T const (*p)[N] . Tendrá que usar un reparto feo o hacer que el parámetro de la función no acepte const .

A primera vista parece que esta conversión debería ser legal. C11 6.3.2.3/2:

Para cualquier calificador q , un puntero a un tipo no calificado con q puede convertirse en un puntero a la versión q calificada del tipo;

Sin embargo, también mire C11 6.7.3 / 9 (was / 8 en C99):

Si la especificación de un tipo de matriz incluye cualquier calificador de tipo, el tipo de elemento es así calificado, no el tipo de matriz.

Esta última cita dice que int const[4] no se considera una versión calificada const de int[4] . En realidad es una matriz no calificada de 4 const int s. int[4] e int const[4] son matrices de diferentes tipos de elementos.

Por lo tanto, 6.3.2.3/2 no permite que int (*)[4] se convierta en int const (*)[4] .

Otra situación extraña en la que aparece este problema con const y arrays es cuando se usan typedefs; por ejemplo:

typedef int X[5]; void func1( X const x ); void func1( int const x[5] );

Esto provocaría un error del compilador: X const x significa que x es const, pero apunta a una matriz de int s no const; mientras que int const x[5] significa que x no es constante sino que apunta a una serie de constantes.

Más información here , gracias a @JensGustedt


Puede escribir cast the array mientras llama a la función. No convertirá automáticamente no const en const. Puedes usar esto.

Sum2D( (const int (*)[])array, ROWS );