cat prova.cpp
#include <stdio.h>
#include <stdlib.h>
void getDimensions(unsigned *, unsigned *);
int (*allocate(unsigned, unsigned))[];
void doSomething(unsigned r, unsigned c, int(*matrix)[*]);
int main()
{
unsigned r, c;
getDimensions(&r, &c);
int(*matrix)[c] = allocate(r, c);
doSomething(r, c, matrix);
free(matrix);
return 0;
}
void getDimensions(unsigned *r, unsigned *c) {
do {
scanf("%u", r);
scanf("%u", c);
} while(*r == 0 || *c == 0); // unsigned -> negative values in input will be considered positive
return;
}
int (*allocate(unsigned r, unsigned c))[]
{
return malloc(r * c * sizeof(int));
}
void doSomething(unsigned r, unsigned c, int(*matrix)[c]) {
unsigned i = 0;
unsigned j;
for(; i < r; i++)
for(j = 0; j < c; j++)
matrix[i][j] = j * i;
for(i = 0; i < r; printf("%c", '\n'), i++)
for(j = 0; j < c; j++)
printf("%u ", matrix[i][j]);
return;
}
Compilando con clang:
clang -Weverything prova.cpp
prova.cpp:6:54: warning: variable length arrays are a C99 feature
[-Wvla-extension]
void doSomething(unsigned r, unsigned c, int(*matrix)[*]);
^
prova.cpp:6:54: warning: variable length array used [-Wvla]
prova.cpp:15:17: warning: variable length arrays are a C99 feature
[-Wvla-extension]
int(*matrix)[c] = allocate(r, c);
^
prova.cpp:15:17: warning: variable length array used [-Wvla]
prova.cpp:15:10: error: cannot initialize a variable of type 'int (*)[c]' with
an rvalue of type 'int (*)[]'
int(*matrix)[c] = allocate(r, c);
^ ~~~~~~~~~~~~~~
prova.cpp:37:12: error: cannot initialize return object of type 'int (*)[]' with
an rvalue of type 'void *'
return malloc(r * c * sizeof(int));
^~~~~~~~~~~~~~~~~~~~~~~~~~~
prova.cpp:41:54: warning: variable length arrays are a C99 feature
[-Wvla-extension]
void doSomething(unsigned r, unsigned c, int(*matrix)[c]) {
^
prova.cpp:41:54: warning: variable length array used [-Wvla]
prova.cpp:48:27: warning: implicit conversion changes signedness: 'unsigned int'
to 'int' [-Wsign-conversion]
matrix[i][j] = j * i;
~ ~~^~~
prova.cpp:41:6: warning: no previous prototype for function 'doSomething'
[-Wmissing-prototypes]
void doSomething(unsigned r, unsigned c, int(*matrix)[c]) {
^
8 warnings and 2 errors generated.
Questo per quanto riguarda il C++, visto che se n'è parlato, mentre per il C:
clang -Weverything prova.c -std=c90
prova.c:6:54: warning: variable length arrays are a C99 feature
[-Wvla-extension]
void doSomething(unsigned r, unsigned c, int(*matrix)[*]);
^
prova.c:6:54: warning: variable length array used [-Wvla]
prova.c:15:17: warning: variable length arrays are a C99 feature
[-Wvla-extension]
int(*matrix)[c] = allocate(r, c);
^
prova.c:15:17: warning: variable length array used [-Wvla]
prova.c:15:10: warning: ISO C90 forbids mixing declarations and code
[-Wdeclaration-after-statement]
int(*matrix)[c] = allocate(r, c);
^
prova.c:30:33: warning: // comments are not allowed in this language [-Wcomment]
} while(*r == 0 || *c == 0); // unsigned -> negative values in input ...
^
prova.c:41:54: warning: variable length arrays are a C99 feature
[-Wvla-extension]
void doSomething(unsigned r, unsigned c, int(*matrix)[c]) {
^
prova.c:41:54: warning: variable length array used [-Wvla]
prova.c:48:27: warning: implicit conversion changes signedness: 'unsigned int'
to 'int' [-Wsign-conversion]
matrix[i][j] = j * i;
~ ~~^~~
prova.c:50:40: warning: possible misuse of comma operator here [-Wcomma]
for(i = 0; i < r; printf("%c", '\n'), i++)
^
prova.c:50:22: note: cast expression to void to silence warning
for(i = 0; i < r; printf("%c", '\n'), i++)
^~~~~~~~~~~~~~~~~~
(void)( )
10 warnings generated.
clang -Weverything prova.c -std=c11
prova.c:6:54: warning: variable length array used [-Wvla]
void doSomething(unsigned r, unsigned c, int(*matrix)[*]);
^
prova.c:15:17: warning: variable length array used [-Wvla]
int(*matrix)[c] = allocate(r, c);
^
prova.c:41:54: warning: variable length array used [-Wvla]
void doSomething(unsigned r, unsigned c, int(*matrix)[c]) {
^
prova.c:48:27: warning: implicit conversion changes signedness: 'unsigned int'
to 'int' [-Wsign-conversion]
matrix[i][j] = j * i;
~ ~~^~~
4 warnings generated.
Che venga compilato senza errori in C non mi stupisce e non l'ho mai messo in dubbio, il fatto è che non è detto che tutti i compilatori supportino tale idioma