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.