Declaring arrays in a header gives me linking problems

Started by
6 comments, last by IrYoKu1 13 years, 5 months ago
Hey guys,

I am working in a little graphics module, and for convience of use I want to put it all in the C++ header (the .h). The problem is that I need to embed two little images in the header (as arrays of chars), and had to define them as static inside of one my classes. As the declaration of these arrays are on the own header file, this indeed give link problems if this header is included in more than one place.

There is a workaround for this? (I know what am doing is really dirty, but want to do it this way, convenience of usage in this very specific case is above all things).

Cheers!
Jorge
Advertisement
It sounds like you're confusing declarations and definitions. You put declarations in the header and put the definitions in source files. If you post specific code for what you're trying then we can help you with the syntax to get it to do what you want. Otherwise for general advice I'd refer you to this article. (See problem number 4)
you can place arrays inside of headers ONLY IF you declare as const and define them as well, like this

// IN HEADER
const int numarray[] = { 5, 457,234,234,234,63,5464,564,6,456,456};

OTherwise, you have to do it like this
// IN HEADER
extern int numarray[];
//IN CCP FILE
int numarray[] = { 5, 457,234,234,234,63,5464,564,6,456,456};



The reason is because you cannot put any variables, classes or anything that actually takes up MEMORY inside a header file. Think of the header as a template for your code. The CPP file are the only files actually allowed to hold items that take up memory.

//HEADER
int k;<---- Not good. You are declaring storage for an item in a header file, you will get linker errors

//HEADER
extern int k;<---- The extern lets the compiler know that the actual storage is going to be in another file -- the cpp file
//CPP FILE
int k =5;


Thats about all



Wisdom is knowing when to shut up, so try it.
--Game Development http://nolimitsdesigns.com: Reliable UDP library, Threading library, Math Library, UI Library. Take a look, its all free.
Yep, I always confuse declarations and definitions somehow :S

I did know that the usual procedure involes putting storage in cpp.

But I want all to be defined in the .h (avoiding a cpp file), even function definitions and arrays, which indeeds causes linking errors. I suppose there is no workaround for this, with the exception of making the class templated (as the linker seems to deal ok with this kinds of re-definitions).

If someone has other idea, it will be welcomed :)

Thanks all!
Instead of trying to create a static class variable in your shared header, how about creating a class method which returns your image data?

Example.h:
class YourClass{	static char* GetImageData()		{		return "\x01\x02\x03\x04...";		}};


Because the method is static, you could call GetImageData() with or without using an instance of the class:
YourClass a;data = a.GetImageData();

- or -
data = YourClass::GetImageData();

I hope this helps
Quote:Original post by smasherprog
The reason is because you cannot put any variables, classes or anything that actually takes up MEMORY inside a header file. Think of the header as a template for your code. The CPP file are the only files actually allowed to hold items that take up memory.

Errr, that's sort of right ...

The problem is that when told to compile a file, the preprocessor gets at the source file and takes all the #include statments and literally copies and pastes the entirety of those files in with the source file. So, header files are never compiled themselves (code-wise, I'm not talking about any pre-compiled header special stuff), so if you attempt to define something inside a header file, then it will be compiled into each source file that includes that header file, and that's when you get linking errors about multiple definitions.

If you're interested, look at the compiler command-line args for whatever you're using and search for "Preprocessor" and you should find an arg that will have the preprocessor output the file after the it is done and you'll see exactly what I mean, there won't be any #include statements, they'll all be replaced by the contents of the header files. That file will be the exact file that the compiler sees.

Quote:Original post by IrYoKu1
Yep, I always confuse declarations and definitions somehow :S

I did know that the usual procedure involes putting storage in cpp.

But I want all to be defined in the .h (avoiding a cpp file), even function definitions and arrays, which indeeds causes linking errors. I suppose there is no workaround for this, with the exception of making the class templated (as the linker seems to deal ok with this kinds of re-definitions).

If someone has other idea, it will be welcomed :)

Thanks all!

You don't need to make it a class by itself. Ideally, what you want to do is declare these things inside the header, using the extern keyword so that the compiler knows you're just declaring that it exists and are not trying to define it, and then define it inside a separate source file.

I know it's not perfect, since you have a source file that has no code, but only a bunch of definitions, but it's really the best way to do things. It will solve your compiler issues, and even if it's in a source file all by itself, your source files are still separated/organised sanely. What I often do is have a misc source file that has a bunch of definitions that are kind of related but don't necessarily require a whole source file individually.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
I managed to solve the problem by:

1. Using const arrays as smasherprog suggested.
2. Making all class functions inline, which indeed resolved all linking problems.

So, now I have all in a hacky yet convenient header.

Thanks all!
There is another thing I would like to polish, but I suspect there is no way of solving it:

I am currently using "#pragma regions" to hide the ugly embeded data:

#pragma region Some Image
const unsigned char image[] = {
0x44, 0x44, 0x53, 0x20, 0x7c, 0x00, 0x00, 0x00, 0x07, 0x10, 0x08, 0x00, 0xa0,
...
}
#pragma endregion


The problem is that by default, when I open the file in Visual C++ 2010, I would like these regions to be collapsed, but by default they are expanded. There is an option or something I can do so that, so that when someone opens the file in Visual C++, these ugly sections are collapsed by default?

Thanks!

This topic is closed to new replies.

Advertisement