# Static const & member arrays

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

## Recommended Posts

So, kind of a two part question here.

//HEADER

private:
static const unsigned int SEND_BUFFER_SIZE;

char m_sendBuffer[SEND_BUFFER_SIZE];

//CPP FILE

const unsigned int Connection::RECEIVE_BUFFER_SIZE = 8192;
const unsigned int Connection::SEND_BUFFER_SIZE = 8192;

This is probably me just not really understanding the basis of how static is compiled but;

1. Given the above code, my understanding is that m_sendBuffer needs a size definition at compile time so that other files including the header have that information available. Is there any way for me to create a member array like that without new or without placing the definition of the size in the header file?

The only reason I ask that is because std::strings are another common thing I use for header constants, but they take up memory so as far as I know I have to define them inside the cpp file. I find it a little annoying to have to place the int constants in the header and the string constants in the cpp file, so I was searching for a way to have both in the cpp file. Is there no option besides the two I listed?

2. Regarding the static, I don't really get the behavior of what it is doing. Why can I declare it without a stated size while the member array requires it? I technically can remove the line where it zero initializes the receive buffer in the cpp file and it will compile just fine. So what are other files seeing? What is that line with a stated size actually doing? I know arrays are just pointers but wouldn't that mean it essentially is pointing to unallocated memory?

I'm mainly just trying to figure out what the actual behavior here is doing and if terrible things happen if I remove the definition of m_receiveBuffer, which still happily compiles.

##### Share on other sites

1: You are correct that people who include your header file need to know how big m_sendBuffer is, and thus you do have to define SEND_BUFFER_SIZE in the header file. I don't think there's a simple way around your problem. You can't define the array size in the cpp file, plain and simple.

2: What you're saying when you declare m_receiveBuffer in the header file is just that there exists a char array that is a static member of the class. You aren't saying where it is or anything else about it, merely that it exists. The compiler will take your word for it and hope that the linker can actually find the definition of that object.  When you define the array in the cpp file, it will need a specific size, because at that point the array is actually created and memory is created for it in the object file. This is in contrast to m_sendBuffer, which is an instance member of your class. Its size must be known because it affects the class definition that it's part of.

EDIT: Regarding you saying that you can remove the definition of m_receiveBuffer and your program compiles just fine: I agree that it should compile, but does it link? If so, are you ever referencing m_receiveBuffer? If not, if you reference m_receiveBuffer, do you then get a linker error? I would expect a linker error (some kind of unresolved external symbol error regarding CClass;:m_receiveBuffer).

Edited by Samith

##### Share on other sites

1: You are correct that people who include your header file need to know how big m_sendBuffer is, and thus you do have to define SEND_BUFFER_SIZE in the header file. I don't think there's a simple way around your problem. You can't define the array size in the cpp file, plain and simple.

2: What you're saying when you declare m_receiveBuffer in the header file is just that there exists a char array that is a static member of the class. You aren't saying where it is or anything else about it, merely that it exists. The compiler will take your word for it and hope that the linker can actually find the definition of that object.  When you define the array in the cpp file, it will need a specific size, because at that point the array is actually created and memory is created for it in the object file. This is in contrast to m_sendBuffer, which is an instance member of your class. Its size must be known because it affects the class definition that it's part of.

Alright thanks, I think that cleared up most of what I didn't get. While I was reading your reply it kind of popped into my head that the static doesn't actually -belong- to the class and is just scoped by it, and thus nobody else needs to know its actual size since it wouldn't be part of any object instances they create.

EDIT: Regarding you saying that you can remove the definition of m_receiveBuffer and your program compiles just fine: I agree that it should compile, but does it link? If so, are you ever referencing m_receiveBuffer? If not, if you reference m_receiveBuffer, do you then get a linker error? I would expect a linker error (some kind of unresolved external symbol error regarding CClass;:m_receiveBuffer).

You're also correct here, I didn't notice at the time until I read what you said and built the entire thing, I was just changing the file and manually compiling the one file, but yes, it does give a linker error. If I give the definition an empty size it also says it can't allocate size 0 so that behavior makes sense as well.

##### Share on other sites

So a little variation on my earlier questioning. Given the following code:

// HEADER

static const unsigned int SEND_BUFFER_SIZE = 8192;

// CPP FILE



Is there any fundamental difference between making the declaration:

static char m_receiveBuffer[RECEIVE_BUFFER_SIZE];


VS

static char m_receiveBuffer[];


Also, this manages to compile and run successfully, despite my IDE actually giving an error that the type isn't defined in the cpp file:

// HEADER

static const unsigned int SEND_BUFFER_SIZE = 8192;

// CPP FILE



Is this undefined?

Edited by Satharis

##### Share on other sites

I think

static char m_receiveBuffer[RECEIVE_BUFFER_SIZE];


and

static char m_receiveBuffer[];


are the same, though the first version gives a bit more info to the compiler which might be used to generate warnings (EDIT: also, the first case can be used in sizeof). It's totally legal to index outside of array bounds in C++, so the array length in the declaration isn't particularly meaningful. This is similar to passing an array type as a parameter to a function:

// these functions all have the same signature, according to the compiler
int foofunc(int myArray[10])
{
// etc
}

int foofunc(int myArray[])
{
// etc
}

int foofunc(int myArray[2])
{
// etc
} 

As for your second question: I honestly am not 100% sure what you get if you define your array like that. My guess is that it's just a zero length array at some location in your executable, and when you try and index into it you're just going to be reading/writing arbitrary memory (ie: undefined behavior, as you suspected). I can't think of any reason why you would want a static array like that. Occasionally those "empty arrays" (there's a specific name for them that I can't think of right now) are useful at the end of a struct like this:

struct MyDiskObject {
int numRecords;
float records[];
};


where MyDiskObject is read off disk (or from the network or whatever), and you know a bunch of floats immediately follow it, so indexing records is indexing into something you know is valid. But that's the only case I know of where empty arrays are useful.

Edited by Samith

##### Share on other sites

If you want that kind of behavior where the size is declared in the cpp, it sounds like you might want a static pointer that gets malloced/new'd somewhere in initialization of the class in the cpp.

Edited by ferrous

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 16
• 11
• 9
• 24
• 47