[comp.lang.c] C question

fawcett@tahoma.UUCP (02/13/87)

I have come across something that I did not expect to find.  I was trying
to print out a special character to the terminal and got a response other
that what I expected.  The code I used was:

main()
{
	union
	{
		char full_message;
		int _message;
	}u;	

	u.full_message = 0xaa;

	printf("%10x\n", (int)u.full_message);
	printf("%10x\n", u._message);
}

What I got when I ran this was:

  ffffffaa
  aa000000

I have tried various other methods for doing this to no avail.
When I tried to print the number as an integer, it worked as expected.
Does anyone know what I am doing wrong, or help me to understand why I got
this response.

John W. Fawcett				Voice: (206) 237-5080
Boeing Commercial Airplane Company	UUCP: ..!uw-beaver!ssc-vax!shuksan
P.O. Box 3707, M/S 66-04			!tahoma!fawcett
Seattle, WA  98124-2207

john@viper.UUCP (02/16/87)

In article <131@tahoma.ARPA> fawcett@tahoma.ARPA (John Fawcett) writes:
 >... The code I used was:
 >
 >main()
 >{
 >	union
 >	{
 >		char full_message;
 >		int _message;
 >	}u;	
 >
 >	u.full_message = 0xaa;
 >
 >	printf("%10x\n", (int)u.full_message);
 >	printf("%10x\n", u._message);
 >}
 >
 >What I got when I ran this was:
 >
 >  ffffffaa
 >  aa000000
 >
  ....................... 
 >Does anyone know what I am doing wrong, or help me to understand why I got
 >this response.
 >
 >John W. Fawcett				Voice: (206) 237-5080
 >Boeing Commercial Airplane Company	UUCP: ..!uw-beaver!ssc-vax!shuksan
 >P.O. Box 3707, M/S 66-04			!tahoma!fawcett
 >Seattle, WA  98124-2207

  I think I can explain.
  Chars on the compiler you're using are defaulting to signed-char.  If you
change the union as follows, it should solve what I think yu mean by "the
problem":

	union
		{
		unsigned char full_message;
		int	      _message;
		} u;

  The cause of all the extra FF's you got was sign extension.  The 0xaa was
taken to mean -86 when it got tossed into the (signed) char variable.  When
this got cast as an int, it was sign extended to maintain the -86 value.
  The aa000000 was a result from using a union.  The union you created is
4 bytes long.  When you place a char in the first byte, and then read it
back as an int, you get the value given because your machine stores int
values with high order byte first.  On a different machine, you might get
000000aa  or even  0000aa00  for the 2nd value depending on the specific
machine you use.
  Hope this answers your question...
  If not, I guess I didn't understand your question.

chguest@pioneer.arc.nasa.gov (Charles J. Guest) (08/02/89)

Everybody in my class has been teasing me because I don't know who
Dennis Richly is.  He supposed to be a big programmer or something.

Help?

lhf@aries5 (Luiz H. deFigueiredo) (08/06/89)

To: chguest@pioneer.arc.nasa.gov.UUCP

In article <4615@eos.UUCP> you write:
>Everybody in my class has been teasing me because I don't know who
>Dennis Richly is.  He supposed to be a big programmer or something.
>
>Help?


Well, I don't know any Dennis Richly either.

But I do know that Dennis Ritchie is a *big* guy anyway.
You can start your own biography of Dennis Ritchie by checking the authors of
"The C Programming Language" ... :-)

Apologies for broadcasting but my mailer doesn't know pioneer.arc.nasa.gov.UUCP

-----------------------------------------------------------------------------
Luiz Henrique de Figueiredo
Conmputer Systems Group
University of Waterloo

internet:	lhf@aries5.waterloo.edu
bitnet:		lhf@watcsg

(possible domains are waterloo.edu and uwaterloo.ca)
-----------------------------------------------------------------------------

bjal_cif@uhura.cc.rochester.edu (Ben Alexander) (11/15/89)

Followups have been redirected to comp.lang.c

In article <5322@wpi.wpi.edu> mhampson@wpi.wpi.edu (Mark A. Hampson) writes:
>I have a question that I have not been able to find an answer that I feel 
>comfortable with regarding the following situation:
>
>I am attempting to allocate a block of memory as follows:
>
>int   m = 10;
>int   n = 10;
>void *block;
>int   block_siz;
>
>block_siz = 2*sizeof(int) + m*n*sizeof(double);
>block = malloc(block_siz);
>
>simple enough...
>
>I now wish to put two integers at the begining of this block of memory:
>
>block = m;
>(block+sizeof(int)) = n;   <---  here is where I am running into probs.

Actually, the line before this is the one that *should* be giving you
problems.  When you say "block = m;" you are telling the complier to make
block point to the address 10.  This means the the space allocated by
malloc is no longer accesible and that you will be accessing (probably)
sensitive areas of memory.  Bad Juju.  I would think that the complier
would give you a warning to the effect of "Non-portable pointer
assignment".

>My intention is to store m in the first int sized space in block and to 
>store n in the int sized space after it.
>
>The compiler that I am using tells me that it does not know the size of 
>block and therefore cannot perform the operation block+sizeof(int).  This
>makes some sence as block is of type void *.  That being the case, how can 
>I perform the operation that I want to?

To do what you want to do you should use the following code:
*((int *) block) = m;
*((int *) block + 1) = n;

The first line assigns the correct value to the first int-sized chunk of
block.  The (int *) typecast gives the complier the size of what block
points to, so it can do the assignment.

In the next line, the addition actually increments block to the next int
as opposed to adding 1 byte to block (that's what the typecast is for).
The indirection of the whole left-hand expression tells the compiler to
store n in the address of block started one int later.

>Thanks in advance:
>Mark A. Hampson

No problem.

Ben Alexander

P.S. I don't read comp.lang.c, so if you want to comment on this, please
e-mail me a copy of your post.