10-06-2008 11:30 AM
using CVI 8.5. i was trying to define a structure containing bit fields. although the structure compiles properly, i do encounter a strange behavior when accessing the individual fields, while the global structure value seems ok. here is the structure:
typedef struct
{
union
{
struct
{
unsigned int flag1 : 1;
unsigned int dummy : 3;
unsigned int flag2 : 4;
unsigned int flag3 : 4;
unsigned int dummy2 : 4;
};
unsigned short all;
} flags;
} flagset;
when setting the "all" member to a value made so that one or more flags, but not all, are false, i do still read individual flags as true, until all flags are set to false.
did i miss something ? is this definition really legal ?
you will find attached a file demonstrating the problem.
Solved! Go to Solution.
10-06-2008 12:50 PM
It does appear to be a bug, but it's a bug with printf. If you look at the variables window while debugging your program or examine any control flow in your program based on these flag values, you'll see that everything is as it should be. What I'm seeing with printf is that it reuses the first evaluated bitfield value (arguments evaluated from right to left) for any subsequent bitfield values. So, when you're printing out field1, field2, and field3, it will print the value of field3 for all three. If you reverse the order of the arguments to printf so that field1 is last, you'll see that all the fields print out as 0 as soon as you've cleared field1.
We'll try to fix this for a future version. Thanks for catching it.
Mert A.
National Instruments
10-06-2008 01:10 PM
10-07-2008 03:49 AM
you are right: the original structure was 16 bit wide. the unsigned int declaration is the result of a test.
there is still one point i need to clarify. i originally noticed this when using the ternary operator (cond ? true : false). so i augmented my test to watch the output with a ternary operator.
when the ternary is used as an argument to printf, the test fails. when the ternary is outside of the printf call, the test passes. i also made the same test with a function other than printf, and the behavior is always correct.
that's where i do not understand: if the ternary is an argument to printf, it should be evaluated _before_ calling printf, the result being pushed on the stack, thus the result should be identical in the 2 cases, and the test should pass.
10-07-2008 10:38 AM
The same issue is at play with or without the ternary operator. It turned out the problem was not specifically with printf, but rather a compiler bug related to evaluation of members of anonymous inner structs. If multiple anonymous inner struct members are evaluated before the compiler actually does anything with the result -- which is the case when passing arguments to a function -- then they will all evaluate to the value of the one that was evaluated last.
Mert A.
National Instruments