There are multiple problems in your code.
In C++, a native array (like your askin
in main()
) is converted into a pointer when passed to a function. So there is no need to declare a dimension on the array in the argument list BUT it is still necessary to pass a second argument, as you are specifying the size.
This means the C++ function should have the form
void singlearrayd(double temp1[], int tempi, std::string str1)
or (equivalently)
void singlearrayd(double *temp1, int tempi, std::string str1)
Note in the above that I have specified the type of the third argument by its full name as std::string
. In a lot of cases, it is better avoid using namespace std
.
The second problem is that you are assuming Fortran array indexing and C++ array indexing are the same. In reality, Fortran array indexing is 1-based (the first element of an array has index one, by default) and C++ array indexing is 0-based (the first element on an array has index zero). Using Fortran array indexing in C++ causes undefined behaviour, because it will access elements outside the valid range.
The third (potential) problem is that your function defines two variables named md_i
(one in the function, and one within the loop). It is better to avoid doing that.
Addressing all of the above will turn your function to (in full)
void singlearrayd(double temp1[], int tempi, std::string str1)
{
for (int md_i = 0; md_i < tempi; ++md_i) // note the differences here carefully
{
cout << temp1[md_i] << "," << str1 << "(" << md_i << ")";
}
}
The fourth problem is that main()
in C++ returns int
, not void
.
The fifth problem is that main()
does not initialize the arrays before singlearrayd()
prints them. In Fortran, arrays that are local to a function are (often) zero-initialised. In C++, they are uninitialised by default, so accessing their values (e.g. to print them) gives undefined behaviour.
int main()
{
double askin[21] = {0.0}; // initialise the first element. Other elements are initialised to zero
double fm[21] = {0.0};
singlearrayd(askin,21,"askin");
singlearrayd(fm,25,"fm");
}
That will get your code working. Practically, however, there are improvements possible. The first improvement is to use a standard container rather than an array. Standard containers know their size, so that allows simplifying your function. Second, pass non-trivial arguments (like containers or strings) by reference - and preferably const
reference if no change is being made to the argument. Unlike Fortran, where function arguments are often passed by reference BY DEFAULT, it is necessary to DELIBERATELY introduce references in C++.
#include <vector>
void singlearrayd(const std::vector<double> &temp1, const std::string &str1)
{
for (std::size_t md_i = 0; md_i < temp1.size(); ++md_i)
{
cout << temp1[md_i] << "," << str1 << "(" << md_i << ")";
}
}
int main()
{
std::vector<double> askin(21); // askin has 21 elements, initialised to zero
std::vector<double> fm(21);
singlearrayd(askin, "askin");
singlearrayd(fm, "fm");
}
C++ containers also support iterators - which are safer in practice AND often more efficient - than using array indexing. I'll leave it as an exercise for you to learn how to use those.
A key message however: don't assume that a simple mechanical translation from Fortran to C++ will work. You have already demonstrated pitfalls of such an assumption. Take the time to learn C++ BEFORE trying to translate too much code from Fortran to C++. That is necessary both to get the C++ code working correctly and also to get it running efficiently.