Casting with pointers? 
Author Message
 Casting with pointers?

if I initiate 'msg' and 'code' as a pointers as follows:

char *msg;
int *code;
.
.
*msg gets a value somewhere down the line e.g. "Test"
.
.

then what does the cast as follows do?

*code = *(int *)msg;

does *code get the size of the message or a large number the same as the
total ascii value?

what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
ascii (I know they don't) then *code would have the integer value of:
00000001000000110000011100001111

is this it?

Luke Tucker



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?



Quote:
>if I initiate 'msg' and 'code' as a pointers as follows:

>char *msg;
>int *code;
>.
>.
>*msg gets a value somewhere down the line e.g. "Test"
>.
>.

>then what does the cast as follows do?

>*code = *(int *)msg;

>does *code get the size of the message or a large number the same as the
>total ascii value?

>what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
>ascii (I know they don't) then *code would have the integer value of:
>00000001000000110000011100001111

It could be 00000001000000110000011100001111, it could be
00001111000001110000001100000001 (the same bytes in reverse order), it could
be something even stranger, or it could be a program crash due to misaligned
pointer. Casting a char * to an int * and then dereferencing it may be useful
as a micro-optimization if you are writing code for only one platform, but if
you don't already know how your platform will handle it, you should probably
stick to portable code and let the compiler do the optimizing.

If you want to yield msg[0]*256*256*256+msg[1]*256*256+msg[2]*256+msg[3],
then write it that way.



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?

Thats the general idea.
But:
1)    the size of the 'int' type is platform dependant and may range
       from 2 - 8 bytes or so.
2)    the value of the resulting int depends on the byte ordering the
       cpu uses: little/big endian.
       with little endian (eg. intel x86 cpus) the bytes are stored with
       least significant bytes first.
       and for big endian (motorola cpus in apple macs), the most
       significant bytes are stored first.

e.g. (assuming 32 bit ints)
char bytearray[] = {0, 0, 0, 1};
int *intval = *((int*)bytearray);
// on little endian platform, *intval == 0x1000
// whereas on big endian platform, *intval = 0x0001

Quote:

> if I initiate 'msg' and 'code' as a pointers as follows:

> char *msg;
> int *code;
> .
> .
> *msg gets a value somewhere down the line e.g. "Test"
> .
> .

> then what does the cast as follows do?

> *code = *(int *)msg;

> does *code get the size of the message or a large number the same as the
> total ascii value?

> what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
> ascii (I know they don't) then *code would have the integer value of:
> 00000001000000110000011100001111

> is this it?

> Luke Tucker



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?


:
:if I initiate 'msg' and 'code' as a pointers as follows:

  That's "initialize".

:char *msg;
:int *code;
:.
:.
:*msg gets a value somewhere down the line e.g. "Test"
:.
:.
:
:then what does the cast as follows do?
:
:*code = *(int *)msg;
:
:does *code get the size of the message or a large number the same as the
:total ascii value?
:
:what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
:ascii (I know they don't) then *code would have the integer value of:
:00000001000000110000011100001111
:
:is this it?

  On some machines, that is indeed what you would see.  But different machines
represent integers differently, especially if they're signed, and there are
variations in the order in which the parts of an integer will be arranged in
memory.
  This code, then, can produce different values when executed on different
platforms.  The C language standard makes no gurantee that a cast like this
will provide a *usable* value on *any* platform.

David G



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?

It should return the value of the first (sizeof(int)) elements in msg,
depending on your architecture that could be 2 or 4 bytes.
Code would be 25940 on little endian systems. (101 * 256 + 84).

String functions essentially iterate through an array of characters until a
NULL is reached. Not integers.

All you are doing with code=(int *)msg is telling the program that the data
for code starts at the first byte of msg. The (int *) typecast just makes
the compiler happy, because you are telling it that you really do want to
point an integer at data that is intended to be used by char's.

(assuming little endian here)
The first byte of msg=84, the second byte is 101. Least significant byte
first, of 2 bytes (sizeof(int)):
84 + (101 * 256) = 25940

On a big-endian system, it's a much larger number, but I forget if those
arch's are LSB first.
it's either (84 + (101 * 256) + (115 * 256 * 256) + (116 * 256 * 256 *256))
or the reverse
(116 + (115 * 256) + (101 * 256 *256) + (84 * 256 * 256 * 256)

One other thing I can't quite remember is if those should be * 128 since
they are signed int's and chars rather than unsigned.

Quote:

>if I initiate 'msg' and 'code' as a pointers as follows:

>char *msg;
>int *code;
>.
>.
>*msg gets a value somewhere down the line e.g. "Test"
>.
>.

>then what does the cast as follows do?

>*code = *(int *)msg;

>does *code get the size of the message or a large number the same as the
>total ascii value?

>what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
>ascii (I know they don't) then *code would have the integer value of:
>00000001000000110000011100001111

>is this it?

>Luke Tucker



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?

I don't know if this code helps, but it will let you know if your machine is
little-endian or not. I got it from a book, which is not in front of me, but I
think it's called C PROGRAMMING: AN INTRODUCTION WITH ADVANCED
APPLICATIONS, or something similar.  I can attribute properly, tomorrow, when I get the
book from my desk.

/* byteord.c: determine how bytes are stored within words in memory   */
#include <stdio.h>
#include <stdlib.h>

union
{
   long Long;
   char Char[sizeof(long)];

Quote:
} u;

int main(void)
{
   u.Long = 1;   /* Low-order byte of long set to 1 */
   if (u.Char[0] == 1)
      puts("Addressing is right-to-left.");
   else if (u.Char[sizeof(long) - 1] == 1)
      puts ("Addressing is left-to-right.");
   else
      puts("Addressing is strange.");

   exit(EXIT_SUCCESS);

Quote:
}  /* main */

Martin


Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?

Quote:

>I don't know if this code helps, but it will let you know if your machine is
>little-endian or not. I got it from a book, which is not in front of me, but
I
>think it's called C PROGRAMMING: AN INTRODUCTION WITH ADVANCED
>APPLICATIONS, or something similar.  I can attribute properly, tomorrow, when
I get the
>book from my desk.

>/* byteord.c: determine how bytes are stored within words in memory   */
>#include <stdio.h>
>#include <stdlib.h>

>union
>{
>   long Long;
>   char Char[sizeof(long)];
>} u;

>int main(void)
>{
>   u.Long = 1;   /* Low-order byte of long set to 1 */
>   if (u.Char[0] == 1)
>      puts("Addressing is right-to-left.");
>   else if (u.Char[sizeof(long) - 1] == 1)
>      puts ("Addressing is left-to-right.");
>   else
>      puts("Addressing is strange.");

>   exit(EXIT_SUCCESS);

>}  /* main */

This is very similar to a suggestion found in the C FAQ:
"20.9:   How can I determine whether a machine's byte order is big-endian
        or little-endian?

A:      One way is to use a pointer:

                int x = 1;
                if(*(char *)&x == 1)
                        printf("little-endian\n");
                else    printf("big-endian\n");

        It's also possible to use a union.

        See also question 10.16.

        References: H&S Sec. 6.1.2 pp. 163-4."

Note the part "It's also possible to use a union."
Now for an editorial.  Using a union is not a good idea, as it invokes
undefined behavior to store an object of type x, and retrieve an object of
type y in the same union.  Now for an editorial to an editorial.  It will
probably work anyway on most machines, whether or not it technically invokes
undefined behavior.  Now for an editorial on an editorial on an editorial.
It's stupid to try something that _might_ fail when something that won't fail
is available.  Because, well, it _might_ fail.  And you might just port it to
some particular machine where it is not a good idea.

Now, if I were king of the forest on some project that needs to know about
endianness, I would rather not worry about it.  How can this be?  Well, if you
use another standard like TCP/IP's hton()/ntoh() or CORBA or ODBC, then it
will be automatically taken care of for you.  So the best answer [IMO] is to
go beyond the bounds of C-Land to an extension standard.
--
Hypertext C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-FAQ ftp: ftp://rtfm.mit.edu, C-FAQ Book: ISBN 0-201-84519-9
Try "C Programming: A Modern Approach" ISBN 0-393-96945-2
Want Software?  Algorithms?  Pubs? http://www.infoseek.com



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?


Quote:

>Note the part "It's also possible to use a union."
>Now for an editorial.  Using a union is not a good idea, as it invokes
>undefined behavior to store an object of type x, and retrieve an object of
>type y in the same union.

No, it's implementation-defined, fortunately or otherwise. It's undefined if
you do it through means other than the union (including pointers which refer
to union members).

Example:

        union intdbl {
                int i;
                double d;
        };

        int foo(double *d, int *i)
        {
                *d = 3.0;
                return *i;              
        }

        main()
        {
                union intdbl u;
                int i;

                u.d = 3.0;
                i = u.i;        /* this access to u.i is well defined */

                foo(&u.d, &u.i);        /* this one is not */
        }

In foo, the aliasing is done through pointers rather than through the union
member access operators, so the behavior is undefined. In main(), the aliasing
is done using the union member access operators which has
implementation-defined semantics. That should probably be taken to mean that
the implementation will ensure that the operation successfully produces
some result. That result could cause failure if it is subsequently used

(This is analogous to mapping an integer to a pointer in an
implementation-defined manner, in which case there is no assurance to the
validity of the resulting pointer value).



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?

: if I initiate 'msg' and 'code' as a pointers as follows:

: char *msg;
: int *code;
: .
: *msg gets a value somewhere down the line e.g. "Test"
: .

: then what does the cast as follows do?

: *code = *(int *)msg;

: does *code get the size of the message or a large number the same as the
: total ascii value?

: what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
: ascii (I know they don't) then *code would have the integer value of:
: 00000001000000110000011100001111

: is this it?

Maybe.  Whatever code points to gets whatever msg, cast to an int pointer,
points to.  However, it may not be possible to convert from char to int
pointer due to alignment problems, and even if that's possible the byte
order of integers is implementation dependant; four byte ints can have
orders 1234, 4321, or even 2143 or 3412.  Experiment with the following
program:

#include <stdio.h>
#include <string.h>
int main(void)
{
  unsigned int buff[8];
  char *cp = (char *)buff;
  strcpy(cp, "test");
  printf("buff[0] is %u, buff is %p, cp is %p, str is %d %d %d %d\n",
                buff[0], buff, cp, *cp, *(cp+1), *(cp+2), *(cp+3));
  return 0;

Quote:
}

and try and explain the results (which will vary, depending on the
machine you compile and run it on).

Will



Fri, 25 Aug 2000 03:00:00 GMT  
 Casting with pointers?

Quote:

>if I initiate 'msg' and 'code' as a pointers as follows:

>char *msg;
>int *code;
>.
>.
>*msg gets a value somewhere down the line e.g. "Test"

Like

 msg = "Test";

Quote:
>.
>.

>then what does the cast as follows do?

>*code = *(int *)msg;

>does *code get the size of the message or a large number the same as the
>total ascii value?

As far as the C language is concerned this results in undefined behaviour,
anything can happen. The main problems are size and alignment.

1. "Test" isn't guaranteed to create an object large enough to hold an
   int (although it will on most existing platforms).

2. "Test" isn't guaranteed to be suitably aligned to be accessible as
   an int. This is more likely to e a real problem, some platforms could
   well trap on this.

Quote:
>what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
>ascii (I know they don't) then *code would have the integer value of:
>00000001000000110000011100001111

That is assuming particular byte and integer sizes and byte order. Even if
the code manages to get this far you have no guarantees that that will be
the result. This isn't something you should generally do in C.

--
-----------------------------------------


-----------------------------------------



Sun, 27 Aug 2000 03:00:00 GMT  
 Casting with pointers?


Quote:
Tucker" writes: >

\ >if I initiate 'msg' and 'code' as a pointers as follows:
\ >
\ >char *msg;
\ >int *code;
\ >.
\ >.
\ >*msg gets a value somewhere down the line e.g. "Test"
\
\ Like
\
\  msg = "Test";
\
\ >.
\ >.
\ >
\ >then what does the cast as follows do?
\ >
\ >*code = *(int *)msg;
\ >
\ >does *code get the size of the message or a large number the same as the
\ >total ascii value?
\
\ As far as the C language is concerned this results in undefined behaviour,
\ anything can happen. The main problems are size and alignment.
\
\ 1. "Test" isn't guaranteed to create an object large enough to hold an
\    int (although it will on most existing platforms).
\
\ 2. "Test" isn't guaranteed to be suitably aligned to be accessible as
\    an int. This is more likely to e a real problem, some platforms could
\    well trap on this.
\
\ >what I though was, say T=00000001, e=00000011, s=00000111, t=00001111 in
\ >ascii (I know they don't) then *code would have the integer value of:
\ >00000001000000110000011100001111
\
\ That is assuming particular byte and integer sizes and byte order. Even if
\ the code manages to get this far you have no guarantees that that will be
\ the result. This isn't something you should generally do in C.

It is not my choice to use this. It is part of the code that runs a
particle accelerator at CERN which I have to figure out.

Luke T



Tue, 29 Aug 2000 03:00:00 GMT  
 Casting with pointers?

Quote:


> Tucker" writes: >
> \ That is assuming particular byte and integer sizes and byte order. Even if
> \ the code manages to get this far you have no guarantees that that will be
> \ the result. This isn't something you should generally do in C.
> It is not my choice to use this. It is part of the code that runs a
> particle accelerator at CERN which I have to figure out.

In that case you're probably going to have to either run the programs
on their original machine, or find some documentation on what's
supposed to happen.  Once you've done this, it might be an idea to
recode the sections of code in question portably or at least document
what they are supposed to do.

--

            http://www.tardis.ed.ac.uk/~broonie/
EUFS        http://www.ed.ac.uk/~filmsoc/



Tue, 05 Sep 2000 03:00:00 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Casting function pointer to void pointer

2. QUESTION: Casting a Pointer to 1 of Many Possible Pointers

3. casting void pointer to be a pointer to a function

4. casting void pointer to be a pointer to a function

5. Type Casting Const Pointers to non const pointers

6. Casting pinning pointer to void *

7. Casting function pointers?

8. Casting function pointers

9. cast function pointer as char* and back

10. Casting a pointer to an int

11. Casting function pointer types

12. casting structure pointers

 

 
Powered by phpBB® Forum Software