cpp Error Duplicate symbol using namespace

451 views Asked by At

This is going to make me nuts !

First of all I already tried solutions from this thread (C++) Linking with namespaces causes duplicate symbol error with no success (maybe I doing it wrong)

Here is what i am attempted to do:

// ofApp.hpp
#ifndef __ofApp_hpp
#define __ofApp_hpp

namespace vec_color {
    glm::vec4 blue = glm::vec4( 0.f, 0.f, 255.f, 255.f );
    glm::vec4 blueViolet = glm::vec4( 0.f, 0.f, 255.f, 255.f );
    glm::vec4 darkRed = glm::vec4( 200.f, 0.f, 0.f, 255.f );
    glm::vec4 green = glm::vec4( 0.f, 255.f, 0.f, 255.f );
    glm::vec4 grey = glm::vec4( 128.f, 128.f, 128.f, 255.f );
    glm::vec4 lightGoldenRodYellow = glm::vec4( 250.f, 250.f, 210.f, 255.f );
    glm::vec4 pink = glm::vec4( 255.f, 192.f, 203.f, 255.f );
    glm::vec4 red = glm::vec4( 255.f, 0.f, 0.f, 255.f );
    glm::vec4 yellow = glm::vec4( 255.f, 255.f, 0.f, 255.f );
    glm::vec4 white = glm::vec4( 255.f, 255.f, 255.f, 255.f );
};

...

#endif

And I then obtain

duplicate symbol 'vec_color::grey' in:
    /Users/[...]/Build/Intermediates.

So I tried

// ofApp.hpp
#ifndef __ofApp_hpp
#define __ofApp_hpp

namespace vec_color {
    extern glm::vec4 blue;
    extern glm::vec4 blueViolet;
    extern glm::vec4 darkRed;
    extern glm::vec4 green;
    extern glm::vec4 grey;
    extern glm::vec4 lightGoldenRodYellow;
    extern glm::vec4 pink;
    extern glm::vec4 red;
    extern glm::vec4 yellow;
    extern glm::vec4 white;
};

...

// ofApp.cpp

vec_color::blue       = glm::vec4( 0.f, 0.f, 255.f, 255.f );
vec_color::blueViolet = glm::vec4( 138.f, 43.f, 226.f, 255.f );
vec_color::darkRed    = glm::vec4( 200.f, 0.f, 0.f, 255.f );
vec_color::green      = glm::vec4( 0.f, 255.f, 0.f, 255.f );
vec_color::grey       = glm::vec4( 128.f, 128.f, 128.f, 255.f );
vec_color::lightGoldenRodYellow = glm::vec4( 250.f, 250.f, 210.f, 255.f );
vec_color::pink       = glm::vec4( 255.f, 192.f, 203.f, 255.f );
vec_color::red        = glm::vec4( 255.f, 0.f, 0.f, 255.f );
vec_color::yellow     = glm::vec4( 255.f, 255.f, 0.f, 255.f );
vec_color::white      = glm::vec4( 255.f, 255.f, 255.f, 255.f );

...

C++ requires a type specifier for all declarations

on each lines variable declaration in cpp file.

I'm stuck if someone have a tip please tell me.

Franck.

3

There are 3 answers

0
Marek R On BEST ANSWER

This way should work:

ofApp.hpp

#ifndef __ofApp_hpp
#define __ofApp_hpp

namespace vec_color {
    extern glm::vec4 blue;
    extern glm::vec4 blueViolet;
    extern glm::vec4 darkRed;
    extern glm::vec4 green;
    extern glm::vec4 grey;
    extern glm::vec4 lightGoldenRodYellow;
    extern glm::vec4 pink;
    extern glm::vec4 red;
    extern glm::vec4 yellow;
    extern glm::vec4 white;
};

...

#endif

ofApp.cpp

#include "ofApp.hpp"

namespace vec_color {
    glm::vec4 blue = glm::vec4( 0.f, 0.f, 255.f, 255.f );
    glm::vec4 blueViolet = glm::vec4( 0.f, 0.f, 255.f, 255.f );
    glm::vec4 darkRed = glm::vec4( 200.f, 0.f, 0.f, 255.f );
    glm::vec4 green = glm::vec4( 0.f, 255.f, 0.f, 255.f );
    glm::vec4 grey = glm::vec4( 128.f, 128.f, 128.f, 255.f );
    glm::vec4 lightGoldenRodYellow = glm::vec4( 250.f, 250.f, 210.f, 255.f );
    glm::vec4 pink = glm::vec4( 255.f, 192.f, 203.f, 255.f );
    glm::vec4 red = glm::vec4( 255.f, 0.f, 0.f, 255.f );
    glm::vec4 yellow = glm::vec4( 255.f, 255.f, 0.f, 255.f );
    glm::vec4 white = glm::vec4( 255.f, 255.f, 255.f, 255.f );
};

or this way: ofApp.cpp

glm::vec4 vec_color::blue = glm::vec4( 0.f, 0.f, 255.f, 255.f );
...

Anyway this way you end with global variables. This is not recommended.

0
R Sahu On
vec_color::blue       = glm::vec4( 0.f, 0.f, 255.f, 255.f );

does not work since you didn't specify the type of the object. Change that to

glm::vec4 vec_color::blue       = glm::vec4( 0.f, 0.f, 255.f, 255.f );

Make similar changes to the other variables also.


As has been pointed out in comments, use of two underscores below

#ifndef __ofApp_hpp
#define __ofApp_hpp

is not to be used in application code. They are reserved for use only by compiler writers. Please don't use them. It's best to remove them altogether and use #pragma once, which is supported by most mainstream compilers.

// ofApp.hpp
#pragma once

namespace vec_color {
    extern glm::vec4 blue;
    extern glm::vec4 blueViolet;
    extern glm::vec4 darkRed;
    extern glm::vec4 green;
    extern glm::vec4 grey;
    extern glm::vec4 lightGoldenRodYellow;
    extern glm::vec4 pink;
    extern glm::vec4 red;
    extern glm::vec4 yellow;
    extern glm::vec4 white;
};
1
pangratt12345 On

sorry if too late response. Just in case someone else stumble upon similar problem.

There is also an approach using inline, static, const keywords to make simultaneous declarations and definitions in header files without splitting to header and source files. You can choose const, static, inline keywords depending on the situation or needs. Example below:

// ofApp.hpp
#pragma once

namespace vec_color {
  inline glm::vec4 blue = glm::vec4( 0.f, 0.f, 255.f, 255.f );
  inline glm::vec4 blueViolet = glm::vec4(0.f, 0.f, 255.f, 255.f);
  inline glm::vec4 darkRed = glm::vec4(200.f, 0.f, 0.f, 255.f);
  inline glm::vec4 green = glm::vec4(0.f, 255.f, 0.f, 255.f);
  inline glm::vec4 grey = glm::vec4(128.f, 128.f, 128.f, 255.f);
  inline glm::vec4 lightGoldenRodYellow = glm::vec4(250.f, 250.f, 210.f, 255.f);
  inline glm::vec4 pink = glm::vec4(255.f, 192.f, 203.f, 255.f);
  inline glm::vec4 red = glm::vec4(255.f, 0.f, 0.f, 255.f);
  inline glm::vec4 yellow = glm::vec4(255.f, 255.f, 0.f, 255.f);
  inline glm::vec4 white = glm::vec4(255.f, 255.f, 255.f, 255.f);
}

You can also consider writing it this way

using color_rgb = glm::vec3;
typedef glm::vec4 color_rgba;

namespace glm::color {
  static color_rgb red3 = color_rgb(255.f, 0.f, 0.f);
  static color_rgb green3 = color_rgb(0.f, 255.f, 0.f);
  const color_rgba blue4 = color_rgba(0.f, 0.f, 255.f, 255.f);
  const color_rgba green4 = color_rgba(0.f, 255.f, 0.f, 255.f);
}

and use it this way

color_rgb opaqueColor = glm::color::red3;
glm::vec4 otherColor = vec_color::green;
glm::vec3 anotherColor = glm::vec3(vec_color::blue);