Public Group

# Keep gettin Linker errors with namespaces in C++

This topic is 4969 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Can anyone help me on this:
------ Rebuild All started: Project: console03, Configuration: Debug Win32 ------

Deleting intermediate files and output files for project 'console03', configuration 'Debug|Win32'.
Compiling...
stdafx.cpp
Compiling...
nmino.cpp
console03.cpp
Generating Code...
nmino.obj : error LNK2005: "int history::rotateCCW" (?rotateCCW@history@@3HA) already defined in console03.obj
nmino.obj : error LNK2005: "int history::rotateCW" (?rotateCW@history@@3HA) already defined in console03.obj
nmino.obj : error LNK2005: "int history::moveRight" (?moveRight@history@@3HA) already defined in console03.obj
nmino.obj : error LNK2005: "int history::moveLeft" (?moveLeft@history@@3HA) already defined in console03.obj
nmino.obj : error LNK2005: "int history::moveDown" (?moveDown@history@@3HA) already defined in console03.obj
nmino.obj : error LNK2005: "int history::moveUp" (?moveUp@history@@3HA) already defined in console03.obj
nmino.obj : error LNK2005: "int history::nothing" (?nothing@history@@3HA) already defined in console03.obj
Debug/console01.exe : fatal error LNK1169: one or more multiply defined symbols found

Build log was saved at "file://d:\dev\cxx\console\console03\console03\Debug\BuildLog.htm"
console03 - 8 error(s), 0 warning(s)

---------------------- Done ----------------------

Rebuild All: 0 succeeded, 1 failed, 0 skipped
I use VC++ 2003, this is how the file looks:
#ifndef INIT_H
#define INIT_H

namespace history
{
int nothing   = 0;
int moveUp    = 1;
int moveDown  = 2;
int moveLeft  = 3;
int moveRight = 4;
int rotateCW = 5;
int rotateCCW = 6;
};

#endif;


##### Share on other sites
You shouldn't declare globals in a header file. They belong in a source file. But to make them visible outside of that source file, you use the extern keyword in the header when declaring them:

Init.h
#ifndef INIT_H#define INIT_Hnamespace history{	extern int nothing;	extern int moveUp;	extern int moveDown;	extern int moveLeft;	extern int moveRight;	extern int rotateCW;	extern int rotateCCW;};#endif;

Init.cpp
#include "Init.h"int history::nothing   = 0;int history::moveUp    = 1;int history::moveDown  = 2;int history::moveLeft  = 3;int history::moveRight = 4;int history::rotateCW  = 5;int history::rotateCCW = 6;

If you don't do it like this, then it will end up reserving space for the variables in every single .cpp in which the header file is included. Then you have multiple copies of the global variables, and the linker doesn't know which one to use when it combines all the .cpps' object files into a single executable.

##### Share on other sites
Ok Agony. If been using classes full of statics in my programms so far, because i never got the namespace to "work" as i expected them to work.

If i have to split things up again in h/cpp file with namespaces then they are not much of a relief to me. Maybe i should stick with my style. ... :|

##### Share on other sites

Is this code ok memory wise:
#ifndef INIT_H#define INIT_Hnamespace history{	static const int nothing = 0;	static const int moveUp = 1;	static const int moveDown = 2;	static const int moveLeft = 3;	static const int moveRight = 4;	static const int rotateCW = 5;	static const int rotateCCW = 6;};#endif;

##### Share on other sites
Constants don't take up any memory. Even if they did, that's just 6 ints... nothing to lose sleep over.

Declaring them static, when you've put them in a header file, is completely pointless.

##### Share on other sites
Quote:
 Original post by FrunyConstants don't take up any memory. Even if they did, that's just 6 ints... nothing to lose sleep over.Declaring them static, when you've put them in a header file, is completely pointless.
Well but doing so will allow me to complile this stuff in VC++2003. Without the statics it won't.

Why do you think it's pointless?

Using the keyword external in a namespace feels somehow weird to me.

[Edited by - Jonus on June 9, 2005 8:39:09 AM]

*bump*

##### Share on other sites
You might try with enums. Only downside, this restricts your constants to integers:

namespace history{  enum eConstants  {    nothing = 0,    moveUp,    moveDown,    moveLeft,    moveRight,    rotateCW,    rotateCCW,    ArbitraryValue = 17,  };}

You can also set every single enum to a specific value. I use enums a lot for flag values.

##### Share on other sites
Quote:
 Original post by EndurionYou might try with enums. Only downside, this restricts your constants to integers:namespace history{ enum eConstants { nothing = 0, moveUp, moveDown, moveLeft, moveRight, rotateCW, rotateCCW, ArbitraryValue = 17, };}You can also set every single enum to a specific value. I use enums a lot for flag values.
Hi there Endurion. I have been using enums a lot in the past. I can't remember what it was, but something with them did really bug me back then. I don't know what it was, maybe something with the switch(){} case or anything else - can't remember. But i had to rewrite alot of stuff because of it.

The best thing for things like this (if both key and value are equivalent in use) would probly be a map, but i don't think i need to go that far (this time).

##### Share on other sites
Quote:
Original post by Jonus
Quote:
 Original post by FrunyConstants don't take up any memory. Even if they did, that's just 6 ints... nothing to lose sleep over.Declaring them static, when you've put them in a header file, is completely pointless.

Well but doing so will allow me to complile this stuff in VC++2003. Without the statics it won't.

Why do you think it's pointless?

The first reason being is using the keyword static to make an internal linkage is deprecated in C++, that pre-dates C++ standardization, if you want to do that then would use anonymous namespaces.

Secondly and i think what Fruny is trying to get at making an internal linkage in headers makes every translation unit have its own version but because they are real constants (because they are defined in the header) it makes no difference.

Yes you have two kinds of constants, real ones, and logically constant, former consumes no storage while the latter does but is read-only. And it all depends on the context which will be which.

Quote:
 Original post by JonusUsing the keyword external in a namespace feels somehow weird to me.

Get use to it [wink], perhaps you should understand what exactly extern does.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 14
• 46
• 22
• 27
• ### Forum Statistics

• Total Topics
634047
• Total Posts
3015231
×