Home > Software design >  C best practice to allocate an array inside the if statement
C best practice to allocate an array inside the if statement

Time:01-21

Recently I get interested in CUDA and it seems much natural to convert C programs into CUDA than Fortran to CUDA (Apart from the main question in this post, is this really true?).

So I am learning C now, and bit surprised that the if statements in C behaves in a quite different way than the Fortran.

For example, the following code works just as expected in Fortran

program test
real(kind=selected_real_kind(15)),  allocatable :: arr_double(:)
integer                          ,  allocatable :: arr_int(:)
logical                                         :: flag_int, flag_double

flag_int    = .false.
flag_double = .true.

if (flag_int) then
  allocate(arr_int(10))
  arr_int = 1
  print *, arr_int
else if (flag_double) then
  allocate(arr_double(10))
  arr_double = 1.
  print *, arr_double
end if

if (flag_int) then
  deallocate(arr_int)
else if (flag_double) then
  deallocate(arr_double)
end if

end program

and its output is like following - again, it is as expected.

  1.00000000000000        1.00000000000000        1.00000000000000 
  1.00000000000000        1.00000000000000        1.00000000000000 
  1.00000000000000        1.00000000000000        1.00000000000000 
  1.00000000000000     

However, its C counterpart does not work and gives error even in the compile-time (icc)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main() {
  size_t dim1;
  bool   flag_int, flag_double;

  flag_int    = false;
  flag_double = true;

  if (flag_int) {
    int (*arr1d) = calloc(dim1, sizeof(*arr1d));
  }else if(flag_double) {
    double (*arr1d) = calloc(dim1, sizeof(*arr1d));
  }

  free(arr1d);

}

It seems that the compile fails because in C the code lines under if () {...} is only local inside the {...}.

Then, if I want to allocate different type of array (i.e. int or double) depending on some if statement, then what would be the best practice to do this?

ps. I want to note that I encountered this problem just playing with the C, and not going to use this kind of ugly code in my actual work.

CodePudding user response:

I don't know much Fortran, but I see that in your Fortran code you have mentioned both arr_double and arr_int up at the top, right under program test. I assume this makes those identifiers available for the later allocate and deallocate statements.

You can do the same sort of declaration in C.

#include <stdlib.h>
#include <stdbool.h>

int main() {
  size_t dim1 = 10;
  double *arr_double = NULL;
  int *arr_int = NULL;
  bool   flag_int, flag_double;

  flag_int    = false;
  flag_double = true;

  if (flag_int) {
    arr_int = calloc(dim1, sizeof *arr_int);
  } else if (flag_double) {
    arr_double = calloc(dim1, sizeof *arr_double);
  }

  free(arr_int);
  free(arr_double);
}

Note that I don't have to check the flags before deallocating with free, because I initialized both arr_int and arr_double to null pointers, and free is required to do nothing when given a null pointer.

As for “what would be the best practice to do this?”, your example is so much a toy program that I don't think there's much useful advice to give.

  •  Tags:  
  • c
  • Related