Use union to share memory in C?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Use union to share memory in C?

Post by Banshaku »

For now, my current project doesn't have any issue with BSS memory yet but it could become an issue someday. Instead to be stuck later and to refactor everything, I thought about 1 idea and want to know if it makes sense.

For example, in a game I may have some state that are not intensive like logo, menu, intro, title etc but they will always requires simple counter or state management variables. The problem is, I define them at the top of every file and it duplicate the memory for something that cannot be run at the same time but is actually for the same use (title cannot be run at the same time as menu so there is no chance of overlap).

Since I need to reset the variable when the state is launched again, I thought maybe I should make some union of common fields that are available from an extern and use the variable when necessary. The only thing I have to be careful is to no mix variables that are shared in the same state. Maybe I could forgo the union and just share a pack of common state variable.

Which one seems most appropriate? I see possible bug if you're not careful with union but it could be useful.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Use union to share memory in C?

Post by rainwarrior »

Unions might be okay, but you could alternatively use overlapping segments for this.

You can use a pragma to change the BSS segment, and then create two segments (and two MEMORY blocks) that overlap the same region of RAM.

That way you wouldn't have to cram all your variables into one big union structure, you could even define them in different files, etc. Not sure how much that's an advantage though.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Use union to share memory in C?

Post by Banshaku »

That's an interesting idea, I didn't think about that and it could come in handy! This "scratch pad' would avoid the union mess. The only thing is to define a proper size at first but I guess if you go over the compiler will tell you anyway.

One thing I don't remember is if you can set a group for variable for specific segment and another group to another segment in the same file. I think you can but that a specific case. I asm it is quite simple to do. Will check the doc for that's but what I remember seems to be an all-or-nothing for that C file.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Use union to share memory in C?

Post by Memblers »

If it helps, overlay is the technical term for what rainwarrior described. It's a common thing in Atari 2600 development, unsurprisingly.
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Use union to share memory in C?

Post by DRW »

I would suggest against overlapping variables via segments and the config file. That's not really obvious from the code and could become a hassle.
Also, the logic of the code should not depend on the memory layout, like in:
"If Var1 is in segment A and Var2 is in segment B, then they share the same space and cannot be used together. If they happen to be in other segments, then everything is fine." --> Not a nice approach.

Instead, whenever I have variables that I want to share, I simply declare them as generic variables somewhere.

Instead of a union (which would require long names like Generic1.MenuStatus), I usually use a #define to give the variable a real name.

Also, Unions are more for stuff where one and the same thing that's thematically related can be either an int or a string or ...
Unions are not really intended for a shared common variable that's simply used for totally different purposes in different places of the code.


So, yeah, a bunch of common variables (Var1, Var2, Var3 etc.) that are then used locally would be my way to go, including a renaming with #define.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Use union to share memory in C?

Post by Banshaku »

@DRW

The union was maybe a bad example from the start and would causes all kind of issue. One of the main reason of "sharing" that memory but with different symbol was to still have a way to access them with their name from asm, if necessary. It may not be useful when all the code is done in C but when you do write some mixed code, it does come in handy. If you use define then in the asm you have to remap them again, which duplicate the effort.

It really depends of the use-case at hand, I think. For now I'm not going to modify the current code base and share segment but may consider a solution when necessary. For now, I'm still fine memory wise.
User avatar
pubby
Posts: 583
Joined: Thu Mar 31, 2016 11:15 am

Re: Use union to share memory in C?

Post by pubby »

I like unions for this and I like the verbosity. You're less likely to mix variables if they're contained in neatly named structs.

Code: Select all

union
{
   struct
   {
        // Vars
   } title_screen;

   struct
   {
        // Stuff
   } game;
} shared;
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: Use union to share memory in C?

Post by Banshaku »

Another thing I would like to do is instead of specifying a pragma for a complete files, I would prefer to specify for a specific symbol or group or symbols. That way I would have some "temp" variables shared with their unique names per C files and more important one just be unique but still, often when you leave a state you don't need that part reserved anymore so if that space could be re-used it would be better. Right now I'm not in a situation were memory is an issue so I guess I should stop early optimizing stuff for nothing ;)
Post Reply