Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > type casting question

Reply
Thread Tools

type casting question

 
 
raj
Guest
Posts: n/a
 
      09-09-2003
Hi,

I am a beginner and need help with the following:

'ifr_data' is (char *)
'args'***** is* unsigned long args[4]

((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;

What does the above statement do.?
Why should we type cast args again it is already of type 'unsigned
long.'
Why do we need to pass the address of ifr_data and later dereference,
if
I understood corrctly, using [].

Cant we do something like:
(unsigned long *) ifr.ifr_data = args



COMPLETE CODE: (remember 'ifr.ifr_data' is char *)
---------------
int br_device_ioctl32(struct bridge *br, unsigned long arg0, unsigned
long arg1, unsigned long arg2, unsigned long arg3)
{
unsigned long args[4];
********struct ifreq ifr;

********args[0] = arg0;
********args[1] = arg1;
********args[2] = arg2;
********args[3] = arg3;

********memcpy(ifr.ifr_name, br->ifname, IFNAMSIZ);
********((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;

********return ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
}
 
Reply With Quote
 
 
 
 
David Rubin
Guest
Posts: n/a
 
      09-09-2003
raj wrote:
>
> Hi,
>
> I am a beginner and need help with the following:
>
> 'ifr_data' is (char *)
> 'args' is unsigned long args[4]
>
> ((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;
>
> What does the above statement do.?


This produces undefined behavior because ifr_data is not guaranteed to
be properly aligned to a ulong type. What you probably want to do is
write a small function or macro which puts the correct bytes in ifr_data
by shifting and masking args.

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
-- unknown
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      09-09-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (raj) wrote:

> 'ifr_data' is (char *)
> 'args'***** is* unsigned long args[4]
>
> ((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;
>
> What does the above statement do.?


Bugger all useful. It casts the address of args to an unsigned long,
then assigns the unsigned-long-was-address to the memory officially
occupied by the char * called ifr_data . The way this is done is not
guaranteed to work (think bus errors), and where it does, is not
guaranteed to result in useful values.

> Why should we type cast args again it is already of type 'unsigned
> long.'


args is not of type unsigned long. It's an array.

> Why do we need to pass the address of ifr_data and later dereference,
> if I understood corrctly, using [].


You're not passing anything. You're casting the address of ifr_data to a
type it does not really have: ifr.ifrdata is treated as if _it_ is an
unsigned long, which is, clearly, wrong.
As for the [0], you don't _really_ need them, you can also use a *. In
fact, that's probably slightly(!) clearer:
*((unsigned long *)(&ifr.ifr_data)) = (unsigned long)args;

> Cant we do something like:
> (unsigned long *) ifr.ifr_data = args


No. For one thing, you cannot assign to a cast expression, because a
cast delivers a simple value, not an lvalue.

> COMPLETE CODE: (remember 'ifr.ifr_data' is char *)
> ---------------
> int br_device_ioctl32(struct bridge *br, unsigned long arg0, unsigned
> long arg1, unsigned long arg2, unsigned long arg3)
> {
> unsigned long args[4];
> ********struct ifreq ifr;
>
> ********args[0] = arg0;
> ********args[1] = arg1;
> ********args[2] = arg2;
> ********args[3] = arg3;
>
> ********memcpy(ifr.ifr_name, br->ifname, IFNAMSIZ);
> ********((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;
>
> ********return ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr);
> }


This is system-specific code. I suspect the secret to that odd
assignment lies in what ioctl() expects in its third parameter. I also
suspect that this was written for a system that does, in fact, make the
guarantees I told you above C itself does not make. Finally, I suspect
this code was not exactly meant for beginners, and suggest you don't
worry if you don't understand it yet.

Richard
 
Reply With Quote
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      09-09-2003

On Tue, 9 Sep 2003, raj wrote:
>
> I am a beginner and need help with the following:
>
> 'ifr_data' is (char *)
> 'args'***** is* unsigned long args[4]
>
> ((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;
>
> What does the above statement do.?


Assigns 'args' to 'ifr.ifr_data', but in a roundabout way that
introduces undefined behavior. *However*, on systems where this
sort of thing does "work," it probably won't change the bit
representation of 'args' during the assignment.

Standard C (no undefined behavior):

ifr.ifr_data = (char *) args;

Standard C (maybe closer to intended effect; has UB):

char *temp = args;
memcpy(&ifr.ifr_data, temp, sizeof temp);


> Why should we type cast args again it is already of type 'unsigned
> long.'


'args' is *not* of type 'unsigned long'. You told us it was of
type 'unsigned long [4]'; which, in this context, decays to a
pointer to the first element in the array -- that is, to a pointer
to unsigned long ('unsigned long *'). That's not the same thing
as 'unsigned long'.

> Why do we need to pass the address of ifr_data and later dereference,
> if I understood corrctly, using [].


You don't "pass" the address of 'ifr.ifr_data' anywhere. You "compute"
it. And see below.

> Cant we do something like:
> (unsigned long *) ifr.ifr_data = args


No. Try that on a conforming compiler, and read the error message
you get.
The '(unsigned long *)' tells the compiler to calculate the value
gotten by treating 'ifr.ifr_data' as an unsigned long. For example,
that value might be 0x55D06A32. Then you're asking the compiler to
assign something to that value. *That doesn't make any sense!*
You can't assign to a cast-expression any more than you can assign
to an addition-expression like '1+1'.

<snip code>

I recommend you try the first alternative method I proposed, and
see whether it works. (But if this is a serious project, be extra-
careful to document the change, and make sure you can tell whether
it's working or not! Just because X compiles doesn't mean X will
work.)

HTH,
-Arthur

 
Reply With Quote
 
Kevin Easton
Guest
Posts: n/a
 
      09-10-2003
raj <(E-Mail Removed)> wrote:
> Hi,
>
> I am a beginner and need help with the following:
>
> 'ifr_data' is (char *)
> 'args' is unsigned long args[4]
>
> ((unsigned long *)(&ifr.ifr_data))[0] = (unsigned long)args;
>
> What does the above statement do.?


The above statement is nonsense. It tries to access a "char *" object
as if it were an "unsigned long", and it casts an (unsigned long *) to
(unsigned long).

The correct way to do what it appears to be *trying* to do is much
simpler:

ifr.ifr_data = (char *)args;

> Why should we type cast args again it is already of type 'unsigned
> long.'


No it isn't - args is of type ``unsigned long [4]''. In an expression
where it's not the operand of either the unary-& or sizeof operators,
it is evaluated as a pointer to the first element of the array, and the
resulting value has type ``unsigned long *''.

> Why do we need to pass the address of ifr_data and later dereference,
> if I understood corrctly, using [].


Because it wants to pretend to the compiler that ifr_data is an unsigned
long (which is a silly thing to do anyway).

> Cant we do something like:
> (unsigned long *) ifr.ifr_data = args


No, the result of a cast operator is not an lvalue, so it can't be
assigned to. That's just as nonsensical as writing:

a + 2 = 10;

- Kevin.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
type casting vs. type converting Toby VHDL 3 09-07-2005 01:42 PM
Another question about inheritance (up-casting and down-casting) kevin Java 11 01-08-2005 07:11 PM
Re: Type casting- a larger type to a smaller type pete C Programming 4 04-02-2004 05:19 PM
Re: Type casting- a larger type to a smaller type heyo C Programming 3 04-01-2004 06:35 PM
Casting between const type** and type** Kevin L C++ 6 08-11-2003 03:39 PM



Advertisments