C++ 'multiple definition' compile error with static enum class members - c++

This is an Arduino project compiled in Visual Studio (using visual micro plugin). I am getting the following error:
AutonomyHandler.cpp.o (symbol from plugin): In function AutonomyHandler::setup() const
(.text+0x0): multiple definition of Module::AvailableCommandKeys
ArduinoProject.cpp.o (symbol from plugin)*: (.text+0x0): first defined here
I am using an enum of CmdKeys within the class definition, and I can use the line of code below to get the available set of keys, but when I try to use it, I get multiple compile errors as seen above for each place I have used it.
Module::AvailableCommandKeys
My Module.h looks as follows:
#ifndef _MODULE_h
#define _MODULE_h
class Module {
public:
enum CmdKeys { Forward, Left, Back, Right, Stop };
static const CmdKeys AvailableCommandKeys[2];
// other definitions...
};
const Module::CmdKeys Module::AvailableCommandKeys[] = { Forward, Back };
#endif
Does anyone know what is happening? I have had this issue before and making the members non-static fixed the issue but I want to keep these enum arrays static.

Since writing this post I found the answer so I thought I would post to help others anyway.
To fix the issue, you just need to move the initialisation of the static members from the definition file (.h) to the declaration file (.cpp)
Module.h looks as follows:
#ifndef _MODULE_h
#define _MODULE_h
class Module {
public:
enum CmdKeys { Forward, Left, Back, Right, Stop };
static const CmdKeys AvailableCommandKeys[2];
// other definitions...
}
const Module::CmdKeys Module::AvailableCommandKeys[] = { Forward, Back };
#endif
Module.cpp looks as follows:
#include "Module.h"
const Module::CmdKeys Module::AvailableCommandKeys[] = { Forward, Back };
// Other code...

Place the line:
const Module::CmdKeys Module::AvailableCommandKeys[] = { Forward, Back };
in a .cpp file.

Related

Extra qualification on member, bezier curve OPENGL

I got error say [Error] extra qualification 'bezierCurve::' on member 'calCurve' [-fpermissive]. Could anyone explain to me why this happen? I've been looking for answer, but the I cannot solve the problem.
#ifndef _BEZIERCURVE_H_
#define _BEZIERCURVE_H_
#include "bezier.h"
class bezierCurve : public bezier{
private:
int numPoints;
float **controlPoints;
float **curvePoints;
void bezierCurve::calCurve(); //and error here
public:
bezierCurve(int numPoints, float *points[3]);
void bezierCurve::setShowPoints(bool showControlPoints); // I got the error here
virtual void draw();
~bezierCurve();
};
#endif
This is an error because it is not valid C++ syntax. The elephant in the room is that VisualC++ has historically not considered this an error. But GCC has since around version 4.
Simply removing the extra qualifications fixes the code.
For example:
#ifndef __ANIMAL_H__
#define __ANIMAL_H__
class Animal
{
...
int Animal::getLegCount();
bool Animal::hasFur();
};
#endif
Is not correct, member must be defined without the Classname:: prefix:
#ifndef __ANIMAL_H__
#define __ANIMAL_H__
class Animal
{
...
int getLegCount();
bool hasFur();
};
#endif
You are confusing declarations and definitions. When you declare a member function, it's in the context of the class already so classname:: is redundant. When you define the body of a function outside of the class, you need the classname:: so that the compiler knows which class it belongs to.
class bezierCurve : public bezier{
void setShowPoints(bool showControlPoints);
};
void bezierCurve::setShowPoints(bool showControlPoints) {
}
this is what output i get. suppose it's not like this.
#kingsley, this shown the output when i'm running the codes after I remove _s from sscanf_s().

how to use not yet defined datatypes in a header?

I am programming on linux using g++ and I often encounter the problem that I need to use a class or data type in a header file which I define later, either at a later point in the header or in another header file.
For instance look at this header file:
class example
{
mydatatype blabla;
};
struct mydatatype
{
int blablainteger;
char blablachar;
};
This will give error because mydatatype is used before its defined
so usually I change it like this:
struct mydatatype; // <-- class prototype
class example
{
mydatatype *blabla; // <-- now a pointer to the data type
// I will allocate the data during runtime with the new operator
};
struct mydatatype
{
int blablainteger;
char blablachar;
};
Now it works. I could often just put the definition above, or include the header which is needed, but I don't want to include headers in a header or juggle with the definition order, it always gets messy.
The solution I showed usually works, but now I have encountered a new phenomenon. This time the datatype is not a class but a typedef, I cant use prototypes for a typedef and I don't want to use the actual datatype which the typedef incorporates.. it's messy too.
Is there any solution to this?
Firstly, the solution you've thought of (prototype and pointer), is unneeded, and slower than just implementing it without the pointer.
The "proper" solution for this, would be creating seperate headers for each type, and then include them in your other header. That way it will always be defined! You can even make them so that they include eachother.
However, if you've ever opened a .h file provided by g++, you've most likely seen this at the start of the header:
#ifndef SOMETHING_H
#define SOMETHING_H
// Code
#endif /* SOMETHING_H */
This is to solve the issue of types redefining themselves.
If they weren't there, and you included the header file multiple times, the types would be redefined, and an error would be thrown. This makes it so that the types are always present, but never included twice.
I hope that helps!
Place each class/type in it's own header file, and then include the relevant header file in other headers where you need it. Use an inclusion guard in each header e.g.:
// SomeHeaderFile.h
#ifndef SOME_HEADER_FILE_H
#define SOME_HEADER_FILE_H
// code
#endif
I disagree that this is messy - it allows you have an organised structure to you project, it allows each class to operate independently of others and without worrying about order, and it's a good idea to place each class in it's own file anyway.
You could just define the class inside the other class like
template<class T>
class vertex {
private:
class edge {
public:
vertex<T> *to;
double weight;
edge() {
weight = INFINITY;
to = NULL;
};
} *paths;
T data;
unsigned nof_paths;
public:
vertex(T val) {
data = val;
paths = NULL;
nof_paths = 0;
}
void addPathTo(vertex<T>*&);
edge* getAllPaths() {
return paths;
};
};
Obviously this works for small classes... if your class is ENORMOUS you'll be better using separate header files like the other guys said.

difference between putting head file(.h) at the beginning and end of another file(.h or .cpp)

Recently , I was compiling libfacebookcpp on mac os. I found a strange usage which I can't understand.
There are two files, AuthorizedObject.hpp and List.hpp.
At the end of file AuthorizedObject.hpp,there is one line :#include "List.hpp".Now I compile successfully. But
when I move that line to the beginning, error occurs. The skeleton of the codes are:
//AuthorizedObject.hpp
class AuthorizedObject
{
public:
...
template<class TType>
void _GetConnection(const ::std::string& uri, List<TType> *list) const
{
LIBFACEBOOKCPP_CHKARG(list);
Json::Value value;
request_->GetResponse(uri, &value);
list->Deserialize(*this, value);
}
...
}
#include "List.hpp" //end
----------------------------------------------------------
//List.hpp
#include "AuthorizedObject.hpp"
class LIBFACEBOOKCPP_API List : public AuthorizedObject
{
private: // private classes
...
}
I guess if put that line(#include "List.h") at the beginning of AuthorizedObject.hpp, the two files include each other by circle. So the compiler don't know how to compile.But put that line at the end will solve this problem? Why? Thank you in advance.
The difference is in what order classes/functions/... are defined, for example:
#include "one.h"
void foo(bar &);
// Will result into:
class bar {};
void foo(bar&);
Which is valid code. On the other hand:
void foo(bar &);
#include "one.h"
// Will result into statements in different order:
void foo(bar&);
class bar {};
Which means using class bar before it was declared, thus error. You also may need to make sure that no declaration will be processed twice (UmNyobe already covered that partially):
#if !defined( MY_HEADER_INCLUDED_)
# define MY_HEADER_INCLUDED_
// Complete content goes here
#endif /* !defined( MY_HEADER_INCLUDED_) */
This way when you include file for the first time, MY_HEADER_INCLUDED_ won't be defined (contents will be "placed" inside the code). The second time (you will include it in the circle) MY_HEADER_INCLUDED_ will be defined and therefore complete body will be skipped.
You're right, that's the problem. You're wrong that the compiler doesn't know how to compile - it does, you're just using it wrong :).
The include guards at the beginning of AuthorizedObject.hpp (I assume it has include guards or a #pragma once directive) will define AUTHORIZED_OBJECT_H (or similar). After that, you include List.h, which in turn includes the header AuthorizedObject.hpp. Because the include guard macro was already defined, the definition of AuthorizedObject is skipped, so List doesn't know about the type, but is uses it, so you get the error.
If you move the include at the end, the definition of AuthorizedObject was already processed by the compiler, so using it inside List.h is valid.

Problem using static variable in a static function

i have a full static class, using a std::map
thats the simplified case
.h
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include <map>
class Keyboad {
static std::map<char, bool> pressed;
static void keyPressedEvent(char _key);
};
#endif
.cpp
#include "Keyboard.h"
void Keyboard :: keyPressedEvent(char _key) {
Keyboard :: pressed[_key] = true;
}
but there is a problem with the static member variable, because i get
Undefined symbols:
"Keyboard::pressed", referenced from:
__ZN15Keyboard7pressedE$non_lazy_ptr in Keyboard.o
(maybe you meant: __ZN15Keyboard7pressedE$non_lazy_ptr)
ld: symbol(s) not found
collect2: ld returned 1 exit status
when i remove it, it runs ok
why do i get this problem, there should be no problem when using a static variable :/
thanks
You need to define the pressed map in your .cpp file:
#include "Keyboard.h"
std::map<char, bool> Keyboard::pressed;
// The rest as before
You should add this to .cpp file
std::map<char, bool> Keyboad::pressed;
Consider static class members as global variables. Compiler should allocate memory for them inside of the only object file. So you should define them in corresponding source file.
A static member in the class definition is just a declaration. You
still have to provide the definition, exactly like you did for the
function. Just add
std::map<char, bool> Keyboard::pressed;
in a source file somewhere. (For mapping chars, you might also
consider a simple
bool Keyboard::pressed[256];
, indexed with the char converted to unsigned char.)
Consider a simpler case. A global variable counter is declared in multiple header files:
int counter; // This appears in 3 HEADER files.
Few source files do refer it. When you compile and link it, compiler would emit linker error saying that counter is already defined in some set of .OBJ files (Error message is dependent on compiler).
To solve this, you just put extern in front of variable (in all header files):
extern int counter; // This appears in 3 HEADER files.
And when you rebuild it, linker will complain that counter is not defined anywhere.
To solve this issue, you define this variable in one source file (any one):
int counter;
And it resolves the issue.
The static-variable of class is nothing but a global variable, which can be accessed by classname::variablename format. The accessibility is same - global.

Unresolved external symbol [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I'm relatively new to C++ (as you can probably tell by the question) and I've hit a problem. I have two files: Drives.h and Drives.cpp
Drives.h
#pragma once
enum MountMode
{
User,
System,
Both,
Auto
};
class Drive
{
public:
Drive(void);
~Drive(void);
BOOL Mount(MountMode mode);
VOID Unmount(void);
BOOL IsConnected(void);
static char* DeviceName;
static char* DrivePath;
};
class Drives
{
public:
Drives(void);
~Drives(void);
};
and my Drives.cpp:
#include "stdafx.h"
#include "Drives.h"
Drives::Drives(void)
{
Drive USB0; //Error happening here
}
Drives::~Drives(void)
{
}
The error is saying that the Drives class constructor, destructor and IsConnected() are all unresolved externals. I'm not sure what I'm missing since I set this class up like the one on cplusplus.com
Thanks in advance
As the error message says, you have not implemented the constructor and destructor of Drive:
Drive::Drive(void) {
...
}
Drive::~Drive(void) {
...
}
Creating a local variable of class type (as you do in Drive USB0;) will invoke that class' constructor, and the destructor will be invoked at the end of the variable's scope; hence the error.
You should implement the other functions of Drive too - declaring a function in a class declaration is essentially a promise that the function will be implemented somewhere.
Yes, those methods have been declared in the Drive class in your header file, but you haven't actually created a body for these methods.
You must either create a body inline in your header file, create a body in a CPP file, or make sure you are linking with an existing file that defines these methods. Otherwise, the error is right, these methods have not been defined.
An Unresolved External Symbol error usually means you have provided a declaration of a function but not its definition.
In your case, since you declared Drive(void) and ~Drive(void) the compiler removes its defaults and expects your definitions to exist, which they don't, so it throws an error.
As a side note: using void in place of empty parenthesis to mean "This function takes no arguments" is a C-Style definition and should not be used.
Also,do not use #pragma once as a substitute for include guards. It is a Microsoft-Specific construct and is not compatible with other compilers. Use actual include guards instead:
#ifndef CLASS_NAME_H
#define CLASS_NAME_H
//CODE HERE
#endif
In the following code you declare two classes(Drive and Drives), but you provide the implementation only for one (Drives)
#pragma once
enum MountMode
{
User,
System,
Both,
Auto
};
class Drive
{
public:
Drive(void);
~Drive(void);
BOOL Mount(MountMode mode);
VOID Unmount(void);
BOOL IsConnected(void);
static char* DeviceName;
static char* DrivePath;
};
class Drives
{
public:
Drives(void);
~Drives(void);
};
To get rid of the error message, you must include an implementation for Drive's class methods. On way to extend your Drives.cpp so that your code may work looks like this:
#include "stdafx.h"
#include "Drives.h"
//Drive class constructor
Drive::Drive(void)
{
//Add initialization code here. For example:
DeviceName = "Name";
DrivePath = "";
}
//Drive class destructor
Drive::~Drive(void)
{
}
//Also add the implementation for Mount
BOOL Drive::Mount(MountMode mode)
{
//implementation for Mount. For example:
return FALSE;
}
//Also add the implementation for Mount
VOID Drive::Unmount()
{
//implementation for Unmount
}
//Also add the implementation for Mount
BOOL Drive::IsConnected()
{
//implementation for IsConnected.For example:
return FALSE;
}
//Drives class constructor
Drives::Drives(void)
{
Drive USB0; //Error happening here
}
//Drives class destructor
Drives::~Drives(void)
{
}
It is also possible if you copy paste-d the code, that you also have the implementation for the Drive class but you save it in another .cpp file, like Drive.cpp. In that case you should either copy all the implementation methods from the other Drive.cpp file to Drives.cpp. Or you should move the declaration of Drive class from Drives.h to Drive.h. In that case you will have clear separation for classes in different files, which is good, but you will have to include Drive.h in the Drives.h file.