tags:

views:

250

answers:

7

For example, suppose I have a buffer called char journal_name[25] which I use to store the journal name. Now suppose a few lines later in the code I want to store someone's name into a buffer. Should I go char person_name[25] or just reuse the journal_name[25]?

The trouble is that everyone who reads the code (and me too after a few weeks) has to understand journal_name is now actually person_name.

But the counter argument is that having two buffers increases space usage. So better to use one.

What do you think about this problem?

Thanks, Boda Cydo.

+2  A: 

Please use person_name[25]. No body likes hard to read code. Its not going to do much if anything at all for your program in terms of memory. Please, just do it the readable way.

thyrgle
+2  A: 

You should always (well unless you're very tight on memory) go for readability and maintainability when writing code for the very reason you mentioned in your question.

25 characters (unless this is just an example) isn't going to "break the bank", but if memory is at a premium you could dynamically allocate the storage for journal_name and then free it when you've finished with it before dynamically allocating the storage for person_name. Though there is the "overhead" of the pointer to the array.

Another way would be to use local scoping on the arrays:

void myMethod()
{
    ... some code
    {
        char journal_name[25];
        ... some more code
    }
    ... even more code
    {
        char person_name[25];
        ... yet more code
    }
}

Though even with this pseudo code the method is getting quite long and would benefit from refactoring into subroutines which wouldn't have this problem.

ChrisF
+8  A: 

Some code is really in order here. However a couple of points to note:

Keep the identifier decoupled from your objects. Call it scratchpad or anything. Also, by the looks of it, this character array is not dynamically allocated. Which means you have to allocate a large enough scratch-pad to be able to reuse them.

An even better approach is to probably make your functions shorter: One function should ideally do one thing at a time. See if you can break up and still face the issue.

dirkgently
+1, this would have been my answer too. I'd like to give a +1 for the `do one thing at a time` as well, but I'm allowed to add only 1 point.
Dacav
@Dacav: Which is also why I didn't put the scope-enforcement solution: It is not a solution in the sense that you are still allocating two buffers and if you are and putting them in separate scopes just go ahead, add a couple of lines and write a function! A direct advantage is writing test cases and subsequent testing becomes trivial.
dirkgently
How about scratchpad_256b if it's 256 bytes?
supercat
@supercat: I try to avoid any variation of the Hungarian notation. IMHO, most modern IDEs render this style unnecessary and personally, I find it jarring.
dirkgently
@dirkgently: I generally don't use types in identifier names, except in cases where several identifiers are likely to be distinguished largely by type, or in scenarios where nothing else about the identifier would indicate what type it is. A global variable called something like "scratchpad" is overly vague and gives no clue what it can hold.
supercat
+13  A: 

The way to solve this in the C way, if you really don't want to waste memory, is to use blocks to scope the buffers:

int main()
{
  {
    char journal_name[26];
    // use journal name
  }
  {
    char person_name[26];
    // use person name 
  }
}

The compiler will reuse the same memory location for both, while giving you a perfectly legible name.

As an alternative, call it name and use it for both <.<

Blindy
+1 This is the way to do it. But note that even without the scopes, the compiler may be smart enough to determine that `journal_name` is not used after a certain point, and so it can use the same space for `person_name`. Even with the scopes, a compiler may allocate both buffers anyway. Just write readable code, and don't worry about "wasting" 25 bytes on the stack here or there, unless you are writing code for a tightly constrained system.
Kristopher Johnson
Wow. Is this a common C programming pattern? This is the first time I see it!
bodacydo
+1 for great technique.
Dacav
Forcing scope like this is very useful, and it's a shame many people don't know it's possible.
You
BTW: This works in C as well (since `{` and `}` delimit scopes in C too)!
dirkgently
another (very useful) use for declaring additional scopes is with switch statements, if you want to create variables inside them.
Tom H
Yea I just removed the C++ part, I didn't notice the OP said C.
Blindy
The compiler _may_ reuse the same memory locations for both. It's not required to, and whether it actually does or not may depend on optimisation settings. (If it really matters in your application, the way to find out for sure is to take a look at the generated code...)
Matthew Slattery
I'm not buying this. Don't take my word for that, try it. Use 750*1024 and 751*1024 for the size and check if that blows the stack.
Hans Passant
`{char b1[750*1024];char b2[751*1024];sprintf(b1, "%d", 1);sprintf(b2,"%d", 2);}{char b2[751*1024];sprintf(b2,"%d", 2);}` crashes. `{char b1[750*1024];sprintf(b1, "%d", 1);}{char b2[751*1024];sprintf(b2,"%d", 2);}` works fine. This is under MSVC 10, release mode.
Blindy
As long as the buffers are equal, or the buffer is the last one on the stack, this optimization seems trivial really. There's no reason why you shouldn't expect it to just work.
Blindy
+1  A: 

If you are worried about memory, and I doubt 25 bytes will be an issue, but then you can just use malloc and free and then you just have an extra 4-8 bytes being used for the pointer.

But, as others mentioned, readability is important, and you may want to decompose your function so that the two buffers are used in functions that actually give more indication as to their uses.

UPDATE:

Now, I have had a buffer called buffer that I would use for reading from a file, for example, and then I would use a function pointer that was passed, to parse the results so that the function reads the file, and handles it appropriately, so that the buffer isn't filled in and then I have to remember that it shouldn't be overwritten yet.

So, yet, reusing a buffer can be useful, when reading from sockets or files, but you want to localize the usage of this buffer otherwise you may have race conditions.

James Black
+3  A: 

If both buffers are automatic why not use this? Most of compilers will handle this correctly with memory reused. But you keep readability.

{
    char journal_name[25];
    /*
        Your code which uses journal_name..
    */
}
{
    char person_name[25];
    /*
        Your code which uses person_name...
    */
}

By the way even if your compiler is stupid and you are very low of memory you can use union but keep different names for readability. Usage of the same variable is worst way.

Roman Nikitchenko
This is the first time I see this pattern of separating the buffers in separate scope. Where did you learn this?
bodacydo
http://ua.linkedin.com/in/romannikitchenko - actually played a lot with C code optimization. Here is my farewell ARM training presentation when I left MindSpeed (look full profile then I-box files). I included several techniques like this.
Roman Nikitchenko
Can you share URL please? I don't have linkedin account. :(
bodacydo
+3  A: 

As an alternative to the previous (good) answers, what about

char buffer[25];

char* journal_name = buffer;

then later

char* person_name = buffer;

Would it be OK ?

Cedric H.
I don't like it. Having, within the same function, two differently meaning names for the same memory space might easily create confusion. `printf("%s has journal named %s", person_name, journal_name);`. It *does* look as if they represent different things.
Lajnold