Jump to content
  • Advertisement
Sign in to follow this  
Jonus

Keep gettin Linker errors with namespaces in C++

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

If you intended to correct an error in the post then please contact us.

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...
Linking...
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 this post


Link to post
Share on other sites
Advertisement
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_H

namespace 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 this post


Link to post
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. ... :|

Thanks for your time/help. :)

Share this post


Link to post
Share on other sites
ok another question about namespaces.

Is this code ok memory wise:

#ifndef INIT_H
#define INIT_H

namespace 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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Fruny
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.
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]

Share this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Endurion
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.
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 this post


Link to post
Share on other sites
Quote:
Original post by Jonus
Quote:
Original post by Fruny
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.


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 Jonus
Using the keyword external in a namespace feels somehow weird to me.


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!