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

Paul

3 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

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.

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.

Knud

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

Laisser un commentaire

Veuillez ouvrir une session pour ajouter un commentaire. Pas encore membre ? Rejoignez-nous dès aujourd’hui