Array Notation compiles with 12.1 but not 13.0

Array Notation compiles with 12.1 but not 13.0

\Dear all,I have following example program which compiled nicely with Intel 12.1 C++ compiler


#include <iostream>

typedef double (*A3)[][];

double sum(int Nx, int Ny, int Nz, double A[Nx][Ny][Nz])


double res = 0;
  for(int x=0;x<Nx;x++) { for(int y=0;y<Ny;y++) { for(int z=0;z<Nz;z++) {  
    res += A[x][y][z];
   } } }
  return res;

int main()
   double *a = new double[8*8*8]; 

   std::cout << sum(8,8,8, (A3) a) << std::endl;
However, swiching to the 13.0 version, compilation aborts with following error message

icc -o test ArrayTest.cpp
ArrayTest.cpp(3): error: an array may not have elements of this type typedef double (*A3)[][];

Is there any new way how to pass arrays to a function ? Note, that I use this principle for large scale

numerical simulation code, where I have to pass an array over many different functions . 

Thanks a lot for any help, Sincerely


3 帖子 / 0 全新

Hi Paul,

This is sort of in the gray area between the C99 VLA (Variable length arrays) standard and C++ standard which doesn't have VLA so there is no definitive right answer. Both gcc and icc supports VLA by default in C++. The 13.0 compiler behavior matches more closely the gcc behavior. The array declaration must have known constant sizes of the n-1 dimensions of an n-dimensional array.

For your example the following declaration of 'a' will produce a valid program:

double (*a)[8][8] = new double[8][8][8];

If the base of an array section has incompletely specified dimensions (such as a pointer variable), the array section must have the length explicitly specified. This is illustrated in the following example.

typedef int (*p2d)[128];
p2d p = (p2d) malloc(sizeof(int)*rows*128);

p[:][:] // error.
p[0:rows][:] // ok.

Note that array notation does not introduce any new types or calling conventions so all array declarations must follow the C, C99, or C++ standards.


Dear Knud,

thank you very much for your response. I did not know before that VLA is enabled by default
in 13.0 compiler. Your response motivated me to try a little more, and I found that using, e.g.

typedef double (*A3)[8][8]

compiles nicely. However, having fixed size arrays for a large numerical code is very inconvenient.
Thus I try to define

typedef double (*A3)[0][0]

which also compiled nicely ! Obviously the cast is just for some sort-of compile time type-safety check (although I am not sure).
The corresponding object file is independent on the cast ( checked by using diff A1.o A2.o which had different typedef's).

Thus I conclude that calling conventions are not influenced by this cast.
Although using a cast like, typedef double (*A3)[0][0], compiles and works, I feel a bit uncomfortable by this hack.
Thus I hoped that the Cilk Plus CEAN standard, may be extended by allowing e.g. to define typedef double (*A3)[:][:]
or something. similar to simplify casts and call the corresponding CEAN function for dynamic multi-dimensional arrays.
I guess, in this case CEAN would gain a lot of popularity for people doing numerical simulations.

Cheers, Paul