telandor
telandor

Reputation: 869

Why can I declare an array in a header file, but not a pointer?

I have a problem with my Consts.hpp file:

#pragma once
#include <stdafx.h>

namespace consts {
    const GLchar* TEXTURE_DIR = "../../blabla/"; // doesn't work
    const GLchar TEXTURE_DIR[14] = "../../blabla/"; // works
};

This file is added to the stdafx.h file. ColladaReader.cpp is the file where I access TEXTURE_DIR. Why does the pointer not work in the namespace? When accessing the constant I get this error:

 Error  5   error LNK2005: "char const * const consts::TEXTURE_DIR" (?TEXTURE_DIR@consts@@3PBDB) already defined in ColladaReader.obj   D:\Privat\code\openglearn\projects\ColladaReader\stdafx.obj

Upvotes: 2

Views: 429

Answers (1)

templatetypedef
templatetypedef

Reputation: 372764

The issue here is that if you put this code in a header file, every .cpp file that includes it will think that it has the one unique copy of consts::TEXTURE_DIR. This will cause a linker error when you compile the code, because the linker will find multiple copies of this variable and will not know which one it should use.

The reason why the first version doesn't work while the second one does is subtle. In C++, any constant at file scope automatically has internal linkage and therefore sidesteps the above problem (since the linker treats each copy as separate). When you declared the array, your array itself is a constant:

const GLchar TEXTURE_DIR[14] = "../../blabla/"; 

However, the pointer you declared is not a constant:

const GLchar* TEXTURE_DIR = "../../blabla/"; 

The reason for this is that the pointer points at GLchars that are constant, but the pointer itself can be reassigned. For example, the line

consts::TEXTURE_DIR = "Now I'm different!"

will compile just fine.

To fix this, change the pointer declaration so that it is a constant pointer:

const GLchar* const TEXTURE_DIR = "../../blabla/"; 

Note the second const here, which means that the pointer cannot be reassigned. This should resolve the linker error.

Hope this helps!

Upvotes: 2

Related Questions