Hello,

I've been having trouble trying to duplicate this program.

My output differs from the sample output I was given for homework. I don't understand whats wrong with my code.

void displayUnion( iUnion );

union integer_union
{
      char c;
      short s;
      int i;
      long l;
};

typedef union integer_union iUnion;

int main()
{
      iUnion value;

      /* char */
      printf( "Please enter a char: " );
      scanf( "%c", &value.c );
      displayUnion( value );

      /* short */
      printf( "%s", "Please enter a short: " );
      scanf( "%hd", &value.s );
      displayUnion( value );

      /* int */
      printf( "%s", "Please enter an int: " );
      scanf( "%d", &value.i );
      displayUnion( value );

      /* long */
      printf( "%s", "Please enter a long: " );
      scanf( "%ld", &value.l );
      displayUnion( value );
      
      /* ending code */
      system( "pause" );

      return 0;
} /* end main */

/* prints each variable in the union */
void displayUnion( iUnion passedIn )
{
      printf( "char  c = %c\n", passedIn.c );
      printf( "short s = %hd\n", passedIn.s );
      printf( "int   i = %d\n", passedIn.i );
      printf( "long  l = %ld\n\n", passedIn.l );
} /* end function displayUnion */

My result:

Please enter a char: a
char c = a
short s = -13215
int i = -858993567
long l = -858993567

Please enter a short: 1
char c = ☺
short s = 1
int i = -859045887
long l = -859045887

Please enter an int: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Please enter a long: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Press any key to continue . . .

Sample output result:

Please enter a char: a
char c = a
short s = 14177
int i = 1982543713
long l = 1982543713

Please enter a short: 1
char c = ☺
short s = 1
int i = 1982529537
long l = 1982529537

Please enter an int: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Please enter a long: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Press any key to continue . . .

Maybe something is wrong with my displayUnion() function?
The problem here is the numbers don't seem to match and I have no idea why even though I believe my code looks correct.

Anyways, help please! ^^

void displayUnion( iUnion );

union integer_union
{
      char c;
      short s;
      int i;
      long l;
};

typedef union integer_union iUnion;

int main()
{
      iUnion value;
     
     //code continues

Hey in your program you are declaring a prototype of function display as shown below:

void displayUnion( iUnion );

And passing an argument of type iUnion to it when a union of type iUnion is not even defined.Hence at that point of time it defines the function in some way but not knowing the real structure of iUnion only.

Try this:

union integer_union
{
      char c;
      short s;
      int i;
      long l;
};

typedef union integer_union iUnion;

void displayUnion( iUnion );

int main()
{
      iUnion value;
   
      //code continues

I don't understand why you expect the same answer.

You are assigning the chat a value 'a', i.e., 97 is stored in the first byte.
Now you are retrieving the value stored in 2 bytes(short), 4 bytes(int and long) so the garbage data will be taken and you are bound to get different values.

The second time the short will get the expected answer since you have assigned it a value, but in the event the char c gets changed to character 1 which is the smiley displayed(See Ascii table) and the int and long will still contain garbage value.

Perhaps you miss understood what union is. Google to know more about it.

> I don't understand whats wrong with my code.
Part of the problem is that the person who set the homework doesn't know either. You might want to start questioning and verifying what they say from some independent sources.

Both are wrong for exactly the same reason, which is that you have uninitialised data.

I don't suppose your "tutor" has even heard about endian problems. Because that's another thing which would shoot this whole thing down, even if you got everything else right.

I don't understand why you expect the same answer.

You are assigning the chat a value 'a', i.e., 97 is stored in the first byte.
Now you are retrieving the value stored in 2 bytes(short), 4 bytes(int and long) so the garbage data will be taken and you are bound to get different values.

The second time the short will get the expected answer since you have assigned it a value, but in the event the char c gets changed to character 1 which is the smiley displayed(See Ascii table) and the int and long will still contain garbage value.

Perhaps you miss understood what union is. Google to know more about it.

Form what I understand, a union is basically a structure that allocates the same space to store its data. So the char, short, int and long variables all share the same storage location (size being that of the largest data type).

I'm only expecting the same answer is because those are the answers provided by my teacher's sample programs. I have already sent him my code and what you see up there is what my teacher said to do. Yet, I still have a differing output than the sample prog. Which is the reason I'm asking here on the forums. I was wondering if maybe the output is different because of system/compiler issues? I did some research online and they talked about Intel using "endian" values, and I'm on AMD. Maybe the sample program was written in a different compiler? (I'm using Visual Studio 2008 btw).

> I don't understand whats wrong with my code.
Part of the problem is that the person who set the homework doesn't know either. You might want to start questioning and verifying what they say from some independent sources.

Both are wrong for exactly the same reason, which is that you have uninitialised data.

I don't suppose your "tutor" has even heard about endian problems. Because that's another thing which would shoot this whole thing down, even if you got everything else right.

I'm not sure if I'm in a position to question the homework. I'm assuming this question has been asked over the years or maybe someone else should be having the same problems. Either way, what basically happens is teachers sample prog output and my output are different. I don't understand why. I don't see anything wrong with my code.

All I'm basically doing is storing a user input into a variable stored inside a union. Then pulling out the value and displaying it as another data type. Which is where some of those garbage values come into play.

void displayUnion( iUnion );

union integer_union
{
      char c;
      short s;
      int i;
      long l;
};

typedef union integer_union iUnion;

int main()
{
      iUnion value;
     
     //code continues

Hey in your program you are declaring a prototype of function display as shown below:

void displayUnion( iUnion );

And passing an argument of type iUnion to it when a union of type iUnion is not even defined.Hence at that point of time it defines the function in some way but not knowing the real structure of iUnion only.

Try this:

union integer_union
{
      char c;
      short s;
      int i;
      long l;
};

typedef union integer_union iUnion;

void displayUnion( iUnion );

int main()
{
      iUnion value;
   
      //code continues

Thanks, I fixed that part. It didn't make a difference though. =P The program still outputs the same results as before.

Different compiler, different time of day, who knows.
When you have undefined behaviour (like relying on the contents of uninitialised data), then all bets are OFF!

Your answer will never be the same as theirs except through sheer dumb luck.
If they can't explain that, or mark you down because of it, then you need another teacher.

Different compiler, different time of day, who knows.
When you have undefined behaviour (like relying on the contents of uninitialised data), then all bets are OFF!

Your answer will never be the same as theirs except through sheer dumb luck.
If they can't explain that, or mark you down because of it, then you need another teacher.

What if I initialize the data then? Would that make a substantial difference? I thought this program is initializing the data with the user input (ie. scanf("%c", &value.c);). =( I guess its something I don't understand here.

Maybe

iUnion value;
memset( &value, 0x00, sizeof value );
// rest of code.

Then try 0x55 0xAA and 0xFF in place of 0x00 and test with each of those as well.

Uninitialized data can never ever be trusted. You are bound to get random values immaterial of the compiler you use and the processor you use. As Salem said. And if you have initialized the long int first(in which case all the bytes in the union would have been initialized) you will get the same answer on all computers that you compile the code, provided they all have little endian byte format or if they all have big endian byte format.

Maybe

iUnion value;
memset( &value, 0x00, sizeof value );
// rest of code.

Then try 0x55 0xAA and 0xFF in place of 0x00 and test with each of those as well.

These are the results I get:

0x00
---
Please enter a char: a
char c = a
short s = 97
int i = 97
long l = 97

Please enter a short: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Please enter an int: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Please enter a long: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Press any key to continue . . .

0x55
---
Please enter a char: a
char c = a
short s = 21857
int i = 1431655777
long l = 1431655777

Please enter a short: 1
char c = ☺
short s = 1
int i = 1431633921
long l = 1431633921

Please enter an int: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Please enter a long: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Press any key to continue . . .

0xFF
---
Please enter a char: a
char c = a
short s = -159
int i = -159
long l = -159

Please enter a short: 1
char c = ☺
short s = 1
int i = -65535
long l = -65535

Please enter an int: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Please enter a long: 1
char c = ☺
short s = 1
int i = 1
long l = 1

Press any key to continue . . .

I have no idea what this means though, does it mean anything to you?

Uninitialized data can never ever be trusted. You are bound to get random values immaterial of the compiler you use and the processor you use. As Salem said. And if you have initialized the long int first(in which case all the bytes in the union would have been initialized) you will get the same answer on all computers that you compile the code, provided they all have little endian byte format or if they all have big endian byte format.

What do you mean by initialize the long int first? Do you mean like:

union integer_union
{
    long l = 0;
};

Like initialize it inside the union then use it?

Or maybe

int main()
{
iUnion value;

value.c = 0;
value.s = 0;
value.i = 0;
value.l = 0;

//rest of code
}

no, int the main function you have initialized the char, then the short, then the int, Now if you initialize int or long first and then the short and byte, you will have a well defined behavior, just like the memset that salem suggested. That's what i ment

no, int the main function you have initialized the char, then the short, then the int, Now if you initialize int or long first and then the short and byte, you will have a well defined behavior, just like the memset that salem suggested. That's what i ment

I see what you mean. If I initialize the l first, then the union is created with 4 bytes and fits all the other data types right? Therefore, you get:

char c = a
short = 97
int = 97
long = 97

The only problem now is that this means nothing in relation to the sample solution provided. =(

When I type in the same input (ie. a, 1, 1, 1)

The result is:
char c = a
short s = 14177
int i = 1982543713
long l = 1982543713

I have no idea what those numbers mean. Like why is the short s = 14177? Why is the int i = 1982543713? Are these just garbage random values generated because the sample prog didn't initialize its variables properly? So I'm sort of chasing an impossible to match answer?

14177 in hex is 0x3761
1982543713 in hex is 0x762B3761
0x61 is lowercase 'a' in the ASCII character set.
0x37 just happens to be the junk in the MSB of the short value.
0x762B just happens to be the junk in the MSW of the long value.

Comments
This should answer the question

14177 in hex is 0x3761
1982543713 in hex is 0x762B3761
0x61 is lowercase 'a' in the ASCII character set.
0x37 just happens to be the junk in the MSB of the short value.
0x762B just happens to be the junk in the MSW of the long value.

Sorry, but this is only my 4th week into learning C and those concepts seem quite advanced. I haven't learned too much about ASCII and hex. But I'll try to understand from my own knowledge.

Since from your example, it looks like the output is appending junk to the beginning of my 'a' hex value. So this means

a = 0x61
when outputted as a short = a = 0x3761 = the 37 being junk
when outputted as an int = a = 0x762B3761 = 0x762B37 = more junk added to the original junk (37).

Thanks for helping me understand. =)

Now the problem is what do I do, should I just submit it as is and make this argument about the small/big endian and the garbage values and how its impossible to duplicate?

That's what I will do. But it is up to you.

Sounds good, but I at least want to go in with a good argument. Don't feel like upshowing my teacher without having a good basis. =P

Thanks for all your help guys. =)

Well I tried executing your code in DevCPP compiler and it worked fine for me.Gave the required output.I too agree with "Salem" may be its just a matter of luck and compiler sometimes.

>may be its just a matter of luck and compiler sometimes.
Yeah, like playing slot in Las Vegas. It's all about luck and compiler, right!

This article has been dead for over six months. Start a new discussion instead.