C++ Function already defined? - c++

At the top of a cpp file, I have
namespace PQL {
class Synonym {
...
public:
...
int size();
};
}
// removing the below chunk makes it work
int Synonym::size() {
return ids.size();
}
Why does the bottom chunk make the code fail? I am creating the implementation of the function? Other functions defined a similar way works.
UPDATE:
Expired (dead) link
The error I got looks like:
Error 1 error LNK2005: "public: int __thiscall
PQL::Synonym::size(void)" (?size#Synonym#PQL##QAEHXZ) already defined
in main.obj H:\Dropbox\Sch\CS3202\SPA_CPP\SPA\pql.obj

Because Synonym isn't a name in global scope.
Either use
int PQL::Synonym::size() {
return ids.size();
}
or implement the method inside the namespace.

Its because your code is in a header file and being included in multiple compilation units:
inline int Synonym::size() {
// ^^^^^^^
return ids.size();
}
Adding inline tells the linker that there may be multiple definitions.
Note: The keyword 'inline' has nothing to do with code inline-ing in modern compilers.
As a very important note.
Your header file contains:
using namespace std;
// and
using namespace PQL;
This is a very bad idea. You are now forcing this on anybody that uses your code. I would never use your header file as it would contaminate my code and cause unforeseen problems. It is OK to do this in your own source files (when you know and understand the issues) but you should never force this on other developers.
See: Why is "using namespace std" considered bad practice?

From your comments, I put this together: You put everything in a single Cpp file and include that file in different other files. Each of those files compiles, and each of those files has an implementation of PQL::Synonym::size(). When linking, the linker sees all those definitions and doesn't know which one to choose.
Split your code into header and source files and just include the header in the other files.

Related

Multiple definition exception in C++

I am starting to learn C++ and am getting this compilation error from my IDE (CodeBlocks). I don't understand why this is happening.
|2|multiple definition of `parser::parseFile()'
|2|first defined here|
I don't see how this could happen. This is my entire code base.
main.cpp
#include "parser/parser.cpp"
int main()
{
return 0;
}
parser/parser.cpp
namespace parser {
void parseFile() {
}
}
Assuming you compiled both main.cpp and parser/parse.cpp you clearly have two definitions of parser::parseFile(): the #include directive just become replaced by the content of the named file (you can use the -E flag with your compiler to see the result).
You probably meant to declare parser::parseFile() in a header file (typically with a suffix .h or .hpp or something like that):
// file: parser/parser.hpp
#ifndef INCLUDED_PARSER_PARSER
#define INCLUDED_PARSER_PARSER
namespace parser {
void parseFile();
}
#endif
... and to include this header file into both translation units.
Your program have violated the One Definition Rule (also known as ODR).
In short, parser::parseFile function have been defined in both of your .cpp files, because on the compiler level, #include <header.h> simply means substituting the entire file contents in place.
Solution to your problem depends on your actual program, though. If you want to solve the ODR rule for class definitions, you can do either of:
1) Add a #pragma once at the beginning on a header. This, although being supported by all major compilers, is not standardized way of protecting from double-including a header.
2) Add an include guard:
#ifndef MY_HEADER_GUARD
#define MY_HEADER_GUARD
// your header contents go here
#endif
If you want to solve the ODR problem for functions and data variables, the above approach won't work because you can still have them defined multiple times in different .cpp files.
For this, you still have 2 options:
1) define your function somewhere outside, namely, in some .cpp file, only leaving its declaration in the header:
// header.h
namespace parser {
void func();
}
// file.cpp
void parser::func() { ... }
2) Declare your function as inline, as inline function are allowed to have multiple definitions by the C++ standard (however, they must be strictly identical up to lexem level):
// header.h
namespace parser {
inline void func() { ... }
}
To sum it up, I'd strongly recommend you go both directions by protecting your header from double inclusion and making sure your function is either inline or gets defined in a .cpp file. With the latter, if your function implementation changes, you won't have to recompile all the files that include your header, but only the one that has the functon definition.
Header files ending with .h(usually) is often used to separate class and function declaration from their implementation.
In Code::Blocks you can add header files by right clicking on your project name -> 'Add files' -> create a new file with .h extension. Following good practise, you should also create a .cpp file with the same name where the implementation is written.
As already answered, in your header file you can first write an include guard followed by your include's (if any) and also your function declarations. And in your 'parser.cpp' & 'main.cpp' you will have to #include "parser.h" since the files depend on eachother.

VC++ LNK2019 Error I can't seem to fix

So I was writing, as a small project, a stress test. Initially, to save time, I just plopped code in a header file. I decided to organise it a bit, and moved everything to a .cpp file and then wrote the header file, but VS2010 presented me with an LNK2019 that I can't seem to fix.
FSTRESS.cpp (Didn't include code, because I doubt it is relevant; ask if you need it)
FSTRESS.h
Main.cpp
The error:
error LNK2019: unresolved external symbol "public: static void __cdecl FSTRESS::Start(unsigned int,unsigned int,unsigned int)" (?Start#FSTRESS##SAXIII#Z) referenced in function _main C:\Programming\C++\FLOPS_Test\FSTRESS\FSTRESS\main.obj FSTRESS_Mk.II
Any ideas on why this is happening? I'm a bit of a C++ noob.
Thanks for any help :)
Your .cpp file is not defining the same classes as the ones you've declared in the .h, but creating different classes with the same name as those declared in the header. The correct way to do this is:
Header file:
class Foo
{
void Bar();
};
Implementation file:
void Foo::Bar()
{
// Do something
}
Alternately, you can declare the functions inline in the header file itself
class Foo
{
void Bar()
{
// Do something
}
};
In the latter case there's no need to create a separate implementation file. In fact, this is exactly what you're doing in fstress.cpp, but then you provide a duplicate declaration in fstress.h without actually defining that class anywhere.
So, you've actually got two separate definitions of the x86 and FSTRESS classes, one in the header file and one in the .cpp file. You're allowed to do that provided that the definitions are identical, but they aren't -- the one in the .cpp file has a bunch of inline code, which isn't there in the one in the header file. (Look up "one definition rule" for more information about this.)
What you actually want to do is this. Your header file is fine (or, at least, I don't see anything conspicuously wrong with it). The .cpp file should (1) #include the header file, and then (2) provide definitions for the member functions, looking like this:
static void FSTRESS::Start(unsigned aMode, unsigned aTest, unsigned aThreads) {
// code goes here
}
(When you have a source file and a corresponding header file, the source file should always #include the header file. This helps to make sure that if there's an inconsistency it gets caught tidily at compile time. I can't tell whether you were already doing that because the top of FSTRESS.cpp is invisible in your screen captures. It might have been better to post the code as text :-).)
As an aside, don't use names that begin with an underscore. A large portion of the space of such names is "reserved", meaning that the C++ implementation can use them internally and Bad Things can happen if your use clashes with its use. It's best just to avoid them all, because that way you don't have to remember what the exact rule is and neither does anyone else reading your code.
You can't just paste the contents of the class declaration with inlined code from the header file into the .cpp file and expect it to work. The implementation of FSTRESS::Start() needs to look morel like the following when you separate it from the class declaration:
void FSTRESS::Start(unsigned _aMode, unsigned _aTest, unsigned _aThreads)
{
//...
}
Also, you should #include "FSTRESS.h" in the FSTRESS.cpp file so there's exactly on declaration of the class that everyone uses (include the implementation bits in FSTRESS.cpp).

Issue with static functions, g++ says the class hasn't been declared

I am trying to compile this code, and g++ keeps telling me that 'TimeFinder' has not been declared
Header File
#ifndef _TIMEFINDER_H
#define _TIMEFINDER_H
#include <vector>
#include "timefinder.cpp"
using namespace std;
class TimeFinder
{
public:
static vector<int> time_from_name(string filename);
static int calc_seconds (vector <int> time);
};
#endif
CPP File
#include "timefinder.h"
using namespace std;
vector<int> TimeFinder::time_from_name(string filename)//Line 14
{
//Method Body
}
int TimeFinder::calc_seconds (vector <int> time1)//Line 37
{
//Method Body
}
Why is this going on? I looked at other examples online, and my code seems to match what works for other people...
Edit: The exact error messages are
timefinder.cpp:14: error: ‘TimeFinder’ has not been declared
timefinder.cpp:37: error: ‘TimeFinder’ has not been declared
Edit2: I'm sorry I'm not very good at this yet, but I would like to thank everyone for their suggestions. Hopefully my code quality will begin to improve because of them.
Do not do this:
#include "timefinder.cpp"
You are pulling your definitions into your header so they appear before their declarations.
There is a lot of other stuff wrong with your code - the use of static members in the first place, passing vectors and strings by value when they should be references, and placing using directives in header files, but removing that #include should fix the immediate problem.
#include "timefinder.cpp"
Header files usually don't include their .cpp implementation file but only whatever other .h file is required to satisfy the definitions required. Usually it's the other way around where .cpp files include the required .h files necessary to fulfill the dependencies.
using namespace std;
This can also cause a lot of havoc and should be avoided in header files. In header files you should always fully qualify your names with their namespace. The reason is if you import this header file into another one that defines the same symbol locally in their namespace like "cout" then both the std::cout and user::cout would clash and cause a compile error or even worse possibly pick the wrong definition and cause a linking error later.

duplicate symbol error C++

I have added some const character in my file as under. The error i get is duplicate symbol _xyz(say). What is the problem with it and how could i get out of this.
const char* xyz = "xyz";
class Abc
{
public:
Abc()
{
}
};
If this is in a header file, you're defining xyz every time you #include it.
You can change the declaration as #R Samuel Klatchko shows. The usual way (if the data isn't const) is like this:
In Abc.h:
extern char *xyz;
In Abc.cpp:
char *xyz = "xyz";
Edited to add
Note that header guards will not solve this problem:
#ifndef XYZ_H
#define XYZ_H
...
#endif
Header guards prevent "redefinition" errors, where the same symbol appears twice in the same compilation unit. That's a compiler error.
But even with header guards the definition of xyz will still appear in every source file that includes it, causing a "duplicate symbol" error, which is a linker error.
It would have been more helpful if the original poster had mentioned that, of course.
The problem is every source file that includes your header file gets it's own copy of xyz with external linkage.
The easiest way to fix that is to give xyz internal linkage. You can do that by making the pointer itself const in addition to having the underlying char's const:
const char* const xyz = "xyz";
I also ran into this issue, but for me the solution was different. I had put overloaded operators (==, !=, <<) in my header file and implemented them. This was causing an issue in other files where I also used ==, !=, or <<. To solve this, I moved the implementation into the .cpp file and left the declaration in the header file.
Edit:
This can also be caused if:
You are including .cpp files instead of .h files. You can fix this by switching the import to use .h instead of .cpp.
You are implementing static functions inside a header file (outside of the class declaration). You can fix this by moving the implementations into a .cpp file (among other solutions).
My use-case:
I had multiple header files a.hpp, b.hpp, and, c.hpp which contained some utility methods.
I had a file util.hpp which acted as an aggregator for the above files.
In my case, the extern did not work but static worked.
I had to use:
header guards to avoid errors in Visual Studio code.
static with functions to avoid compile-time errors.
Check out this article too.

Anyone knows how to fix compile error: LNK2005? (Source Code inside)

I have the below code in stdafx.h.
using namespace std;
typedef struct {
DWORD address;
DWORD size;
char file[64];
DWORD line;
} ALLOC_INFO;
typedef list<ALLOC_INFO*> AllocList;
//AllocList *allocList;
Without the commented code (last line), it compiles just fine. But when I add the commented code, Im getting the following error.
error LNK2005: "class std::list >
* allocList" (?allocList##3PAV?$list#PAUALLOC_INFO##V?$allocator#PAUALLOC_INFO###std###std##A)
already defined in test.obj
Im using Visual Studio .NET 2003. Anyone has any idea what that is and how to solve it?
Don't put definitions in header files, just declarations. Declarations specify that something exists while definitions actually define them (by allocating space). For example typedef, extern and function prototypes are all declarations, while things like struct, int and function bodies are definitions.
What's happening is that you're most likely including stdafx.h in multiple compilation units (C++ source files) and each of the resulting object files is getting its own copy of allocList.
Then when you link the objects together, there's two (or more) things called allocList, hence the link error.
You would be better off declaring the variable:
extern AllocList *allocList;
in your header file and defining it somewhere in a C++ source file (such as a main.cpp):
AllocList *allocList;
That way, every compilation unit that includes stdafx.h will know about the external variable, but it's only defined in one compilation unit.
Based on your further information:
I was trying to follow http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml, I assume that all those code are meant to be placed in the stdafx.h. Any other alternatives, pax?
My response is as follows.
I wouldn't put them in stdafx.h myself since I think that uses some MS magic for pre-compiled headers.
Make a separate header file mymemory.h and put your function prototypes in it, for example (note that this has no body):
inline void * __cdecl operator new(
unsigned int size,
const char *file,
int line);
Also in that header, put the other prototypes for AddTrack(), DumpUnfreed(), etc., and the #define, typedef and extern statements:
extern AllocList *allocList;
Then, in a new file mymemory.cpp (which also contains #include "mymemory.h"), put the actual definition of allocList along with all the real functions (not just the prototypes) and add that file to your project.
Then, #include "mymemory.h" in every source file in which you need to track memory (probably all of them). Because there are no definitions in the header file, you won't get duplicates during the link and because the declarations are there, you won't get undefined references either.
Keep in mind that this won't track memory leaks in code that you don't compile (e.g., third-party libraries) but it should let you know about your own problems.
I was trying to follow this article, I assume that all those code are meant to be placed in the stdafx.h. Any other alternatives pax?