3

I have a project in code blocks that uses many different files - quite often written by other programmers. At the moment I have a situation in which I have two different sub-projects containing function named in the same manner. Let's say: F(int x). So F(int x) is defined in two source files in two different locations and they have two different headers. Also I have created two different namespaces for those headers:

namespace NS1
{
 extern "C"{
  #include "header1definingF.h"
 }
}
namespace NS2
{
 extern "C"{
  #include "header2definingF.h"
 }
}

But still compiler complains that it has multiple definition of F(int x). How can I workaround this in Code::Blocks (In Visual Studio it works just fine).

EDIT: To be more clear those headers include C code. I haven't thought it will be so messy. There are like thousands of source files using other projects including thousands of functions again... so what to do. I have absolutely no idea how to make it work.

Misery
  • 689
  • 2
  • 8
  • 25

6 Answers6

7

I wonder why it works on Visual Studio, but not on Code Blocks. This suggests you do have an include guard. Does this help?

Project->Build options...->Linker settings (tab)
-Wl,--allow-multiple-definition
silvioprog
  • 580
  • 1
  • 8
  • 18
doctorlove
  • 18,872
  • 2
  • 46
  • 62
  • It works. But still I need to think of something more safe. And how do I know it uses the proper definition? But at the moment it works just fine. Thanks. – Misery Jul 22 '13 at 15:40
3

I can't understand your problems clearly, but i think you should understand how the compiler works, when you use gcc to compel your program, your program first will be run include operator, that means if you include a header, the compiler will copy the header file to the file. if you include the header twice there will be a twice define error.so you must guarantee once,you can use

#ifndef __FILE_NAME__
#define __FILE_NAME__
// your code
#endif

If your problem is the redefine the function, you should know how the compiler distinguish the function, i think your problem is you do not use the namespace when you use the function.

xiaoy
  • 41
  • 5
  • Isn't it okay to include the same header file multiple times as you can declare the same non-member function multiple times in C++? – young Jul 22 '13 at 14:42
  • Actually the conflict is in two C files even without calling any of those functions – Misery Jul 22 '13 at 15:20
  • 1
    @Misery I think that's because linker still sees the multiple definitions of the same function signature. Did you compile it in Debug mode? In Release, the error will probably disappear as not-called-functions are optimized out. and check my updates and hope it helps~ :) – young Jul 22 '13 at 15:29
  • @young: I have edited my question as it is even more complicated. Can I add a namespace in a *.c file? For example using __cplusplus directive? – Misery Jul 22 '13 at 15:32
  • 1
    @Misery In visual studio, you should be able to compile .c file as an c++ file by right clicking on that file and change one of c++/advance properties. don't remember exact name of the option. google it and give it a try. no idea about Code::Blocks. :) – young Jul 22 '13 at 15:43
3

The problem is that the namespace do not work for C functions (extern "C"). Here is a simple sample which do not compile:

namespace NS1
{
 extern "C"{
  int f()
  {
   return 1;
  }
 }
}
namespace NS2
{
 extern "C"{
  int f()
  {
   return 2;
  }
 }
}

In this case the two functions are different but have the same name: f(). If you just declare the functions, it will compile but they must refer to the same function.

This second sample works fine. The functions have the name NS1::f() and NS2::f() which are differents.

namespace NS1
{
 int f()
 {
  return 1;
 }
}
namespace NS2
{
 int f()
 {
  return 2;
 }
}

If you want to use two different c code, you can use objcopy which can help you to have a NS1_f() and NS2_f() function. After that you should rename all functions of the libraries in your includes. In this case, no namespace are used. This is normal, there is no namespace in C. Equivalent functions:

int NS1_f()
{
 return 1;
}
int NS2_f()
{
 return 2;
}
1

I believe you have to edit cpp files as well to nest the two functions into a corresponding namespace. Plus, you have to choose which function you want to call like namespace::function() or you can use using namespace with either of the namespaces you created. Hope this helps!

[Updates #1] It is easier to get confused between the declaration and definition of a function. Remember that you can redeclare non-member functions. Thus, if a header file only contains non-member function declarations, it is safe to include it multiple times in one translation unit (a cpp file). Adding ifndef/define in a header file is a good habit for avoiding potential problems but that is not what resolves your problem.

Your problem is that you want to have two different function definitions with the same function signature(its name and arguments) and that's not allowed in C++. You can either change one of their signatures or put them into a different namespace (which you are trying but without touching their definitions). Both ways require you to edit files containing their definitions.

[Updates #2] As you updated the question with that the code is in C, I've searched and found this:

What should I do if two libraries provide a function with the same name generating a conflict?

it will surely help you to understand your problem more clearly and find a solution. Good luck!

Community
  • 1
  • 1
young
  • 2,163
  • 12
  • 19
1

Short of editing the .cpp files themselves and renaming the functions (which is not a practical solution), your options are either making sure to only include one of the header files with duplicate functions at a time (which could be a huge maintainance problem) or, and this would be my recommendation, make use of namespaces. They will save you a ton of hassle in this situation.

Pat Lillis
  • 1,152
  • 8
  • 19
  • I believe you still get 'multiple definition' error even if you include only one header as linker really inspects all object files and notices that there are two definitions with the same function signature. – young Jul 22 '13 at 14:54
1

You may need one of two things. The following is called a Header Guard:

#ifndef MYHEADER_H
#define MYHEADER_H

//your header code goes here

#endif

This way the header is only included once per object file that asks for it. However, if you want to have two methods with the same identifier, they have to be part of different Namespaces:

namespace myspace1{
    void func(void);
};
namespace myspace2{
    void func(void);
};

Other than that, there's not really much else you can do. You shouldn't have two functions with the same name in general. Also, you would have to modify this in the header files that you mentioned.

You are allowed to declare functions as often as you want, however they can only have ONE definition.

Joseph Pla
  • 1,600
  • 1
  • 10
  • 21