How to choose from functions with the same name in C++ - c++

I have this simple code in C++
#include <something.h>
#include <something2.h>
int main()
{
my_function();
return 0;
}
function with name my_function is defined in something.h and also in something2.h How to choose whichone I want to use without editting included files?

One solution is to use
namespace something_one
{
#include <something.h>
}
namespace something_two
{
#include <something2.h>
}
This works well if all the code is in the headers.
Otherwise you have to resort to #defines, stub functions implemented in carefully crafted compilation units, or a robust conversation with the global namespace polluter.

Assuming that actual definition resides in something.cpp (or .c) and something2.cpp (or .c),
Link only one of something.o or something2.o at the time of creating main application executable, depending upon from which file you want function to get executed.
With linking the correct file, you do not need to change any source code.
you might have to declare them as extern "C" at the point declaration and definition if you are compiling it as c++ files with g++ or gcc -std=c++0x or gcc -std=c++11.

Related

Is this C header written properly?

I am learning (trying) how to write my own C/C++ headers, and get functions out of the body of my code. For this I wrote nyanlib.h, and nyan.cpp
Ignoring that its a trivial program, please tell me if the header is written correctly, or if I am making serious mistakes? The code works though.
Here is nyan.cpp:
#include <iostream>
#include <unistd.h>
#include "nyanlib.h"
using namespace std;
int main()
{
while( true )
{
print_nyan(); //function from nyanlib
sleep(1);
}
return 0;
}
and Here is nyanlib.h
Also, Would nyanlib.h be a shared library or a static library?
What you have as nyanlib.h should be renamed to nyanlib.cpp. Then nyanlib.h would contain only the following:
#ifndef NYANLIB_H
#define NYANLIB_H
void print_nyan();
#endif
You can then compile the library as an object file:
g++ -c nyanlib.cpp
This gives you nyanlib.o. So now your main file contains just a prototype of print_nyan() from the header file so it knows how to call it.
Then you compile the main program:
g++ -c nyan.cpp
g++ -o nyan nyan.o nyanlib.o
Yes and no. While it is a valid header, you are using it a bit strangely. Most of the time, a header is used as a way to expose methods and variables related to the class and not to perform functionality.
For your case if you want to make it "better", I would bring the implementation of the print_nyan() function into the cpp file, and just leave a prototype of the function in the header.
And I would say that it is neither a static nor a shared library since it has a main. If you wanted to make it a library, you should make a separate header and source file that defines the print_nyan() function, make that your library, and use that library in your main function.

Conditional compilation confusion and failure

I want to compile different files with a common *.c file. Like I want to compile A.c common.c xor B.c common.c but I can't figure out how to achieve that.
Can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile
So let's say I have 3 files: A.c, B.c and common.c.
A.h and B.h define an enum enum {Mon, Tues, Wed...} in different ways. And that enum is used in common.c. So I can't just do in common.c:
#include "A.h"
#include "B.h"
What I thought of doing is to use preprocessor directives:
In common.h
#define A 1
#define B 2
In A.c
#define COMPILE_HEADER A
And in common.c
#if COMPILE_HEADER == A
#include A.h
#end
This doesn't work, of course, because the compiler didn't visit the A.c file to find #define COMPILE_HEADER A
So can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile?
It's pretty complicated to explain, but I'll give it a try.
Explaination
The compiler, for example gcc, gets the input files provided, includes (literally just copy-pastes) the header files into their respective places (where the #include directive is located) in the *.c file, then compiles the file to the object (*.o) file. No executable is created. Here comes the linker, which is included in gcc. It takes the *.o files and links them into one executable.
The problem is, that the files are compiled independently, and then linked together. I mean, that predefinition like int func(int param); is like saying to compiler "Hey man, don't worry about any usage of func in the code, the linker will care". Compiler then just saves this usage as external symbol in the corresponding *.o file, and when linker is doing his job, he firstly finds the location of the symbol definition (the function implementation) and then just points to it whenever the func is called.
Try to include function definition in header file, then include it in 2 or more files from same project (compiled/linked together). Compiler will say it's ok, since the code is correct and the generated code is valid. Then, the linker will try to link it into one executable and he would have to decide which version of the same name-param function should it link to. Since most developer tools are not really good at making the right choices, he will just yell at you saying "hey man, you gave me two definitions of same function, what to do now?". This results with an error like this:
obj\Release\b.o:b.cpp:(.text+0x0): multiple definition of 'func(int)'
obj\Release\a.o:a.cpp:(.text+0xc): first defined here
What about having two main in one project?
obj\Release\b.o:b.cpp:(.text.startup+0x0): multiple definition of 'main'
obj\Release\a.o:a.cpp:(.text.startup+0x0): first defined here
Both files compile, but they cannot be linked together.
The header files are meant to contain class definitions and function predefinitions to allow you to write them only once, and then share between all files that want to use them. You can always just type class definitions for each file separately (as long as they stay same) and use them just like you would use them in .h file, same applies for function predefinitions.
There comes your problem. You have to compile only one file, not include only one. You can do this by using the preprocessor trick, but I wouldn't reccomend as solution, since it can be solved much easier (I'll tell you how in a moment).
TL;DR; (The actual answer without explaination)
You can #ifdef / #ifndef both files, then in another *.c define (or not define) some value. For example:
A.cpp
#include "t.h"
#ifdef USE_A
int func(int a)
{
return a + 5;
}
#endif
B.cpp
#include "t.h"
#ifndef USE_A
int func(int a)
{
return a * 10;
}
#endif
T.h
#ifndef T_H
#define T_H
//Or comment to use B
#define USE_A
int func(int a);
#endif // T_H
main.cpp
#include <iostream>
#include "t.h"
using namespace std;
int main()
{
cout << func(3);
}
Notice that the #ifdef/#ifndef are after the #include, so the preprocessor knows which one to compile. Also, it's not possible (at least I can't think of any way) to make the definition in any .c file, because they are compiled separately (as described above). You could use the -D switch, but that involves messing with build configurations in environments and if you want to do that it's better to try the second solution presented bellow.
Better answer
You should choose one file to compile with each version. It hardly depends on your needs, but basically instead of using g++ main.cpp a.cpp b.cpp you should compile either a.cpp or b.cpp. If you are using integrated environment like Visual Studio or Code Blocks, the configuration managers allow you to decide which file to include. I mean, those Debug/Release dropdowns can contain your own entries, which will customize your project. Then, switching between the A.cpp and B.cpp is just a question of choosing appropiate option in the always-visible bar in your environment.
If you want a more detailed tutorial on how to manage configurations on Code::Blocks or Visual Studio create appropiate question on stackoverflow and it will be answered in no time :)

one or more multiply defined symbols found error - simple

I'm trying to deal with this problem for some time and I can't seem to find the solution. I'm getting error:
one or more multiply defined symbols found
I faced this error while dealing with something more complicated, but even simple examples like this one don't work for me. Here is my main.cpp:
#include "defs.cpp"
int main()
{
string a = "A";
printIt(a);
}
, and here is my defs.cpp:
#include "header.h"
void printIt(string a)
{
cout << a;
}
, and this is my header.h:
#include <string>
#include <iostream>
using namespace std;
void printIt(string a);
I guess this is something trivial, but please don't rage if you think this is duplicate, because I'm a beginner and I didn't understand more complicated examples. Some help would be appreciated.
When you see #include "defs.cpp" you need to get very suspicious: cpp files are not meant to be included; only header files are designed for that.
Instead of including a cpp file, write a header for it. It appears that you have a suitable header already - your header.h, which contains the forward declaration of printIt:
void printIt(string a);
Now replace #include defs.cpp with #include "header.h", and compile your code. This should fix the problem.
Compiling this depends on the system where you are trying it out. On UNIX-like systems, you would write
g++ defs.cpp main.cpp
./a.out
You should not #include a CPP file. Only include header files containing the function prototype definitions. If no such header file exists, put the function prototype in your program (for eg. in file where main is written).
In your case, you are including (directly/indirectly) the CPP file which is having the definition of the function. Since same definition is compiled through CPP files, compiler is putting them into .OBJ file (known as intermediate or object files). The linker finally attempts to combine these Object files, and says some function (symbol) is multiply defined.
In main.cpp you are including defs.cpp which includes a definition of printIt. So the translation unit corresponding to main.cpp defines printIt.
However, you are also compiling defs.cpp which defines printIt. defs.cpps corresponding translation unit thus defines printIt too.
Combining both into one program would lead to multiple (yet equivalent) definitions of this function which is forbidden by the ODR. Remove the #include directive and your program should link correctly.
This is because you are including:-
#include "defs.cpp"
and due to this there are multiple definitions of method printIt.
These are some basic rules:-
1) You must always include only header files in your source files. Even then you have to make sure header files are included only once because if it is included more than once then there could again be problem of multiple definition.To protect against that your header files should contain header gaurds.
2) C++ always adheres with single definition rule. However , you can have as many declaratons as possible as long as all declarations are consistent.

How to use a function defined in another file with g++?

This is a really basic question, and I have found a lot of conceptual answers online, but failed to actually make it work.
Here is what I have:
file source.cc
#include <iostream>
int myfunc() {
return 42;
}
int main() {
return 0;
}
and then I create an object file source.o via:
g++ -c source.cc
finally, I use
ar rvs source.a source.o
to get the source.a static library.
Now, here comes trouble.
file user.cc looks like this:
#include <iostream>
#include <source.a>
int main() {
std::cout << myfunc();
}
where I evidently want to use the function defined in the library, but when trying to compile the user.cc:
g++ user.cc -o user
the error I get is:
user.cc:2:22: fatal error: source.a: No such file or directory
compilation terminated.
#include is compile time and must be C/C++ header (not library) containing e.g this
extern int myfunc();
than you have to use linker to compile it all togehter (specify all the files needed on the command line)
In addition to what others already wrote on the syntax to properly use g++ on the command line, you may want to consider the following notes on your code organization.
In your library code, you should not define the main() function. The definition of main() should instead be part of the code that uses your library, i.e the file user.cc in your example.
Moreover, you may want to distribute to the clients of the library a header file, that they can use to import the declarations of the functions exported by the library.
So, consider defining some files like this:
Header File:
// library.h -- Public header for your library's clients
#pragma once // or use #ifndef/#define/#endif "header guards"
// Functions exported by your library:
// their *declarations* go in the library's public header file;
// their *definitions* go in the library's implementation file(s) (.cc, .cpp)
// (exception: inline functions/methods, that are implemented in headers).
int myfunc();
// Add some other exported functions...
// NOTE: "extern" not needed in C++!
Implementation File:
// library.cc -- Library implementation code
#include "library.h" // library public header
#include <...> // headers required by this implementation code
// *Define* functions exported by the library
int myfunc() {
return 42;
}
// ...other function implementations...
Then, the library's client will just do:
File containing main() and using your library:
// main.cc (or user.cc or whatever you call it)
#include <iostream> // For std::cout, std::endl
...#include any other required header file...
#include "library.h" // Your library public header file
int main() {
// Call library's function
std::cout << myfunc() << std::endl;
}
// NOTE: main() is special: "return 0;" can be omitted.
Don't #include a library archive. It does not contain source code. It contains object code. Put it on the linker's command line.
Compile with g++ -c user.cc.
Link with g++ -o user user.o source.a.
In C++ (and C99), every function you call much be declared ahead of time. To do this you provide the "signature" of the function, without the the definition. In your case, this would be the statement
int myfunc();
which tells the compiler that myfunc is a function which takes no arguments and returns an int. Typically you would include this function declaration in a header.
A .a file is a compiled archive which does not contain C or C++ code, so #include-ing it into a C++ file will not work. Instead you need to create a C or C++ header, and add the .a archive to the list of files to be linked into the final executable. With g++, this is quite easy, you can say
g++ user.cc source.a -o executable
for example.
By default the #include <...> construct (with angle brackets) search system directories to find the specified files. To search other directories you can use the -L option, and to link with your library you need to use source.a in the command line. Like this:
g++ user.cc -L/path/to/library source.a -o user
A couple of ideas to add to the discussion
1) You should create a header file called source.h that contains the line
int myfunc();
or,
extern int myfunc();
2) In user.cc at the top should be a line
include "source.h"
This will tell the compiler the function is defined
3) I think you should take the main function out of source.cc, or at least make it static
As others have pointed out, you can't include a library file (source.a)
your compile and link process should work as is.
You can use headear files using #include. If you want to use libraries you have to tell the linker where to look for library files.
Check these articles for static and dynamic libraries:
Static and dynamic libraries
Using libraries in VS2005
Using libraries in Code::Blocks

Linking in several C object files that contain functions with equivalent signature

Lets say I have a C++ program and I want to call functions from a C object file in it. The constraint is that I'm not allowed to make any changes to the C source files.
In this case I would include the C header as extern "C" in my C++ file, call the function, compile the C object using gcc -c, and pass the result to g++ along with the actual C++ sources.
I guess what I would also do is to put the C-header #include inside a named namespace block in the C++ file, as to keep the local namespace clean (who knows what other fancy stuff there is in the .h file).
What now if I need to call functions from two C object files. Lets say that they have different signatures. But there are also some duplicate functions in the object files. Wouldn't my linker blow up at this point if I tried to pass both objects to g++ at the same time? Same for globals.
Again: I'm not allowed to change ANY of the C sources. Else I would just rename the .c files to .cxx, wrap their contents and the contents of the corresponding headers inside namespace bla { } and feed everything to g++.
(Yes, C is not a subset of C++, as has already been mentioned in one of the comments)
Your last paragraph has a good solution - why not make a C++ file something like this:
namespace c_namespace_1 {
#include "CFile1.c"
}
namespace c_namespace_2 {
#include "CFile2.c"
}
And so on.... then you could compile this file as C++ and not have to modify the original sources.
You could bring the C executable codes in as individual binary data files and handle the function pointer casting yourself - basically do the linker's job for it. If the binary directly wouldn't work, get the assembler output of the C files and wrap them in functions similiar to the above suggestion of namespaces.
How about compile each C subsystem to its own LIB file, then compile a separate C++ LIB file that includes the appropriate C LIB and provides wrapped function calls to only the C functions in its .LIB
ie:
file1.c => file1.lib
file2.c => file2.lib
Wrapper1.cpp + file1.lib => Wrapper1.lib
Wrapper2.cpp + file2.lib => Wrapper2.lib
Application.cpp + Wrapper1.lib + wrapper2.lib => Application.exe
Note that this off the top of my head and I have no idea if the linker will still go boom
Of course you could compile Wrapper1 and Wrapper2 to dll's instead of Lib's and that would ensure the linker doesn't go boom!
This is pretty hacky, but one solution is to rename the function(s) in question via macros, so that they have different names as far as the linker is concerned.
For example, if you have too functions called foo, one of which takes an int and the other of which takes a double, in files IntFoo.c and DoubleFoo.c, you can compile them like this:
cc -Dfoo=IntFoo -o IntFoo.o IntFoo.c
cc -Dfoo=DoubleFoo -o DoubleFoo.o DoubleFoo.c
Then in your C++, you can do this:
#define foo IntFoo
extern "C" {
#include "IntFoo.h"
}
#define foo DoubleFoo
extern "C" {
#include "DoubleFoo.h"
}
#undef foo
There are lot of caveats here: you have to ensure that the symbol foo is used only as the name of the function you want, you have to ensure that you define the macros appropriately everywhere that the symbol foo is used. If there are duplicate symbols, you have to define macros for those as well.
It is probably a much better solution to just fix the C files.