C++: Addition of ". cpp" implementations in Visual Studio and GCC

Asked

Viewed 133 times

4

In C++, what is observed in a quick internet search is the orientation that only ". h" files should be included. A sample of this can be observed here and especially here.

In Visual Studio, the inclusion of only ".h" with #include ... no problem, as long as the implementation files ". cpp" are included in the project. This ensures that they will be compiled and there will be a reference valid for class methods. However, this does not seem to be the case for GCC (g++). See the code below:

Mt. h

#ifndef MT_H
#define MT_H

namespace Subsistema {
  class Mt {
  public:
    int soma(int i, int d);
  };
}
#endif

Mt.cpp

#include "Mt.h"

namespace Subsistema {
    int Mt::soma(int i, int d) {
    return i + d;
  }
}

main.cpp

#include <iostream>
#include "Mt.h"

int main(int argc, char *argv[]){
  Subsistema::Mt * t = new Subsistema::Mt();

  std::cout << "Soma: " << t->soma(3, 5) << std::endl;

  delete t;

  return 0;
}

The above code will compile perfectly in Visual Studio even if there is no #include Mt.cpp, provided that it is included in the project. But it will NOT do so in g++, with the following error message:

/tmp/ccQVvF4r: In Function 'main':

main.cpp:7: Undefined Ference to 'Subsystem::Mt::soma(int, int)'

collect2: error: Ld returned 1 Exit status

This error could easily be solved by adding the macro #ifdef __GNUC__ , as follows:

#ifndef MT_H
#define MT_H

namespace Subsistema {
  class Mt {
  public:
    int soma(int i, int d);
  };
}

#ifdef __GNUC__
#include "Mt.cpp"
#endif

#endif

But the point is, this is a solution, but is the appropriate solution (best practice) to the situation? I need a solution, which as far as possible, independent of the compiler used.

NOTE: This question is closely related to How to include header and cpp without resulting in LNK2005 error in Visual Studio

1 answer

1

The error message is not a build error. It is a linkage:

/tmp/ccQVvF4r.o: In function 'main':
main.cpp:7: undefined reference to 'Subsistema::Mt::soma(int, int)'
collect2: error: ld returned 1 exit status

It means that the linker the object file containing the method implementation is not found Subsistema::Mt::soma(int, int).

The Mt.cpp should be passed as a parameter to the compiler and not included through the directive #include.

This should compile your program without errors:

$ g++ main.cpp Mt.cpp -o teste
  • Thanks again. But is this serious? If I have a project with more than 50 . cpp, will I have to pass them all on the gcc command? Wow, I’m sorry to surprise you, but that doesn’t seem consistent, on the contrary, counter-productive. There’s no cleaner, more automated alternative?

  • 2

    In large projects it is not compiled manually like this. For this we use the famous Makefiles

  • 1

    @guinalz I made an answer about the use of makefiles in a project, and also involves one or two C file compilation cycle thingies: https://answall.com/a/213804/64969; for C++, the behavior is very similar. It also has many more cool things to wear with makefile more advanced mode, that you barely write the file of make, but this is usually a more advanced use that you will feel the need after. When you feel the need for more advanced things, we’ll be here

  • Explanation of Makefile: https://answall.com/q/154102/64969

Browser other questions tagged

You are not signed in. Login or sign up in order to post.