1
votes

I'm trying to link a C++ file with my Fortran 90 program, but I'm running into a link error when using gfortran.

My Fortran files are compiled with:
gfortran -c -o obj/file.o file.f90 -O0 -g3 -ffree-line-length-none -fcheck-array-temporaries -fbounds-check and my C++ file is compiled using g++-4.7 -c -o obj/cppfile.o cppfile.cpp -O0 -g3 -std=c++11

Then, all are linked together with gfortran:
gfortran -o program obj/file.o obj/cppfile.o -O0 -g3 -ffree-line-length-none -fcheck-array-temporaries -fbounds-check -lm -llapack -lc -lgfortran -lgcc -lstdc++

When doing this, I get the following link errors:

Undefined symbols for architecture x86_64:
"std::basic_string, std::allocator::basic_string(std::basic_string, std::allocator >&&)", referenced from:

std::basic_string, std::allocator > std::operator+, std::allocator >(char const*, std::basic_string, std::allocator >&&) in cppfile.o
std::basic_string, std::allocator > std::operator+, std::allocator >(std::basic_string, std::allocator >&&, char const*) in cppfile.o
std::basic_string, std::allocator > std::operator+, std::allocator >(std::basic_string, std::allocator >&&, std::basic_string, std::allocator >&&) in cppfile.o
std::basic_string, std::allocator > std::operator+, std::allocator >(std::basic_string, std::allocator >&&, std::basic_string, std::allocator > const&) in cppfile.o
component::component(component&&) in cppfile.o "std::basic_string, std::allocator >::operator=(std::basic_string, std::allocator >&&)", referenced from:
function in cppfile.o
component::operator=(component&&) in cppfile.o

ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: * [program] Error 1

My c++ file looks like this:

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <math.h>
#include <stdio.h>
#include <vector>

using namespace std;

struct component
{
    string num;     // numerator of component
    string den;     // denominator of component
    int ind;        // index of variable
};

extern "C"{
void subroutine_ (int num, const int* array)
{
    ...
    return;
}

Any thoughts as to why this would be happening? I made sure to link the -lstdc++ library. Could it have something to do with my use of the C++11 standard, related to the string library?

1
What happens if you instead try to link with: g++ -std=c++11 -o program obj/file.o obj/cppfile.o -O0 -g3 -lm -llapack -lgfortranNikos C.
@NikosC.: That's the most likely answer.Benjamin Bannier
Doing that, it links without error, but running the program immediately fails with redmech(25962) malloc: *** mmap(size=18446744073587937280) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug Operating system error: Cannot allocate memory Memory allocation failedKyle Niemeyer
I should mention, the Fortran code holds the main program, i.e., PROGRAM. Also, it compiles and runs without error using gfortran to link without the c++ subroutine. Also, in my last comment, redmech is the actual name of the program.Kyle Niemeyer
Alright, after doing a little testing, when linking with gfortran the problem appears to be a combination of the -std=c++11 and either a string vector or vector of my struct component. In a simpler code, if I remove -std=c++11, I can have vectors of either type without problem.Kyle Niemeyer

1 Answers

1
votes

One solution appears to be to remove the -std=c++11 from the compilation of the C++ code. With it, combining linking C++ code with a vector of strings (or structs that contain a string) causes the above errors.

I'm going to file a bug in the GCC Bugzilla on this, and use my solution as a workaround in the meantime.