I’m trying to port some software to V5 that requires the controller keys be put into anonymous structs and unions, but it was originally written in C so there are some problems with porting it.
I had a theory on why this might not be working, so I wrote a minimal version of your code that worked, then I copied your code as-written and it worked. The project in question. You might be doing something else that’s causing this other than what you’ve listed here, or my compiler is fixing some mistake in usage here that VEXcode’s is not.
I tried the same code as John in VEXcode, works ok for me.
But honestly, why bitfields ? They always cause problems, it’s not like you really have to save memory.
code
int main() {
struct keys {
union {
struct {
union {
struct {
unsigned char a : 1;
unsigned char b : 1;
unsigned char sel : 1;
unsigned char strt : 1;
};
unsigned char keys1 : 4;
};
union {
struct {
unsigned char u : 1;
unsigned char d : 1;
unsigned char l : 1;
unsigned char r : 1;
};
unsigned char keys2 : 4;
};
};
unsigned char c;
};
} keys;
keys.keys1 = 0xf;
printf("%d %d %d\n",keys.a,keys.b,keys.keys1); this_thread::sleep_for(1000);
keys.a = 0;
printf("%d %d %d\n",keys.a,keys.b,keys.keys1); this_thread::sleep_for(1000);
keys.b = 0;
printf("%d %d %d\n",keys.a,keys.b,keys.keys1); this_thread::sleep_for(1000);
}
When I first read the title, I thought it was a plot for an sci-fi action movie inspired by a comic book: Mutating member of anonymous causes memory error
If I knew what it really was, I may have chosen not to click on it - my brains still hurt from looking at that code.
I assume it is a not a compilation, but a runtime error. I don’t remember exact details, but I once run into compiler mistakenly evaluating something like keys.a not to an offset 0 inside the outer structure, but to absolute address 0 for the memory reference.
I understand it is a third party project and you don’t want to make a lot of code modifications. But could you try to reduce the number of nesting levels and see what happens:
struct keys {
union {
unsigned char c; // byte (8 bits)
struct { // nibbles (4 bits)
unsigned char keys1 : 4;
unsigned char keys2 : 4;
};
struct { // single addressable bits
unsigned char a : 1;
unsigned char b : 1;
unsigned char sel : 1;
unsigned char strt : 1;
unsigned char u : 1;
unsigned char d : 1;
unsigned char l : 1;
unsigned char r : 1;
};
};
} keys;
After changing some things, I figured out that changing a variable inside of the if statement is the problem. The issue is, I need an if statement in order to make this code useful.
if(Controller.ButtonA.pressing() == true) {keys.a = 0;}
that fails and causes an error keys.a = 0; outside of an if isnt a problem though.
can you post a simple, complete example that demonstrates the problem. There are too many things we don’t know about how you are using this variable, is it global or local, things like that.
Is it even possible for this to be the cause of the problem?
I don’t think it can have anything to do with having it nested in the if statement.
Maybe your controller call is the problem?
Or maybe it actually only crashes when keys.a != 0 (when the button has not been pressed yet)?
The code is here. I determined that it was some problem in the line if(Controller.ButtonA.pressing() == true) {keys.a = 0;}
because the cout statements dont stop until this line.
Are you supposed to have a delay in the main loop?
Aside from that, I’m guessing the issue is caused by keys not being 0.
ps. If you were to do this project in pros, they have a feature that when the program crashes it outputs the current stack addresses, which you can use to find the exact line that made it crash.
yea, I can look at that as well in some of my development tools. It seems to crash in the standard library, but I doubt it has anything to do with the keys variable, probably a memcpy or something like that.
putting a delay in the loop just slows down the emulation, and delays the crash, it seems to happen somewhere around 60000 iterations. But that’s about as much as I have time to debug today. It’s something to do with the emulator corrupting memory, but theres too much code to debug quickly. Adding many std::cout (without any loop delays) is also not helping, you are filling the IO buffers too fast and they probably will cause VEXcode some issues.