[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

C variable retyping

Rich Touper

7/1/2011 9:22:00 PM

C allows type casting in which a variable is converted from one type
to another.

Does C (whatever standard) allow the type of a variable to change,
within a statement, avoiding the conversion? And if so, provide an
example of how its done.

Example:
int a=23;
int b=34;
char c='a';
int * p_int=(int *) &c;

// type casting
// c is converted into type integer, then b is added.
(int) c + b;

//retypeing
(type int) c + b;
// similar action
*p_int + b

Ignoring alignment issues, storage size issues, etc., c is retyped to
an integer, no conversion is done, and c is used, within the
statement, as an integer, not a char.

Thanks
11 Answers

Ben Pfaff

7/1/2011 9:47:00 PM

0

Rich Touper <rt97316@yahoo.NOSPAM.com> writes:

> C allows type casting in which a variable is converted from one type
> to another.
>
> Does C (whatever standard) allow the type of a variable to change,
> within a statement, avoiding the conversion? And if so, provide an
> example of how its done.

No, C doesn't have that.
--
Ben Pfaff
http://be...

Keith Thompson

7/1/2011 9:56:00 PM

0

Ben Pfaff <blp@cs.stanford.edu> writes:
> Rich Touper <rt97316@yahoo.NOSPAM.com> writes:
>> C allows type casting in which a variable is converted from one type
>> to another.
>>
>> Does C (whatever standard) allow the type of a variable to change,
>> within a statement, avoiding the conversion? And if so, provide an
>> example of how its done.
>
> No, C doesn't have that.

Fortunately.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson

7/1/2011 10:00:00 PM

0

Shao Miller <sha0.miller@gmail.com> writes:
> On 7/1/2011 4:21 PM, Rich Touper wrote:
>> C allows type casting in which a variable is converted from one type
>> to another.
>
> Hmm... Not that I know of. As far as I know, there isn't any "type
> casting" in C, but a value of some type can be converted to a value of
> some other type.

"Type casting" is a common (but arguably incorrect) term for the cast
operator.

A conversion is an operation that takes a value of some type and
converts it to another type. A cast, written as a type name in
parentheses, is an operator that specifies such a conversion. There are
also implicit conversions.

"Type casting" is something that happens to TV and movie actors. 8-)}

>> Does C (whatever standard) allow the type of a variable to change,
>> within a statement, avoiding the conversion? And if so, provide an
>> example of how its done.

Why would you want to do this? What are you trying to accomplish?

[...]

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Rich Touper

7/1/2011 10:14:00 PM

0

On Fri, 01 Jul 2011 17:52:35 -0500, Shao Miller wrote:
> On 7/1/2011 4:21 PM, Rich Touper wrote:
>> C allows type casting in which a variable is converted from one type to
>> another.

As everyone pointed out, "converted" should be "promoted", and "during
evaluation" should have been tacked on the end. That would have helped
on the semantics of the question, but is still vague.

> Hmm... Not that I know of. As far as I know, there isn't any "type
> casting" in C, but a value of some type can be converted to a value of
> some other type.

That seems to be the concensus of opinion. I certainly never heard of
it, but thought it may be an obscure, rarely used feature.

>> Does C (whatever standard) allow the type of a variable to change,
>> within a statement, avoiding the conversion? And if so, provide an
>> example of how its done.
>>
>> Example:
>> int a=23;
>> int b=34;
>> char c='a';
>> int * p_int=(int *)&c;
>>
>>
> A few concerns with that last line including "alignment issues, storage
> size issues, etc."

Wasn't attempting to start a huge thread on pointers, just using it to
illustrate a point.

>> // type casting
>> // c is converted into type integer, then b is added. (int) c + b;
>>
>>
> I don't think so. The value of 'c' is converted to an 'int' value, that
> is added to the value of 'b', then the result is unused. 'c' remains a
> 'char' throughout.

Exactly. The pomotion happens according to the standard, but only the
value of c is used, and because c is type char, 1 byte.

>> //retypeing
>> (type int) c + b;
>
> What is 'type'? It's not a C keyword. Is it some macro you haven't
> shared?

I don't have a way to define it. But the point is IF c could be "retyped"
to an int, then sizeof(int) bytes would be used during evaluation. As
other posters pointed out, there would be alignment issues, unknown bytes
at &c+1 to &c+sizeof(int), etc...

I'll take this as a resounding NO. No such thing as "retyping".
Thanks

>> // similar action
>> *p_int + b
>>
>>
> Assuming the original initialization of 'p_int' succeeded and still
> points to the first byte of the object identified as 'c', the expression
> '*p_int' attempts to re-interpret the bytes at the address of 'c' as an
> object representation for an 'int' value.
>
>> Ignoring alignment issues, storage size issues, etc., c is retyped to
>> an integer, no conversion is done, and c is used, within the statement,
>> as an integer, not a char.
>
> You can do similar things with unions for re-interpreting an object
> representation of a value of one type as an object representation of a
> value of a different type.
>
> I don't understand why one would wish to ignore alignment issues,
> storage size issues, etc.
>
> To answer the only question in this post, you might be interested in C's
> definition of "effective type." For example, in:
>
> void * vp = malloc(sizeof (int[10]);
>
> if 'malloc' succeeds, the object pointed to by 'vp' has no declared type
> and no effective type. An effective type can later be established by
> using an lvalue to read or modify the object.
>
> int (* ten_ints)[10] = vp;
>
> if (ten_ints) {
> (*ten_ints)[0] = 1;
> /* ... */
> (*ten_ints)[9] = 10;
> }
>
> Now the effective type for the allocate storage has been established as
> the type 'int[10]'.

Shao Miller

7/1/2011 10:53:00 PM

0

On 7/1/2011 4:21 PM, Rich Touper wrote:
> C allows type casting in which a variable is converted from one type
> to another.
>

Hmm... Not that I know of. As far as I know, there isn't any "type
casting" in C, but a value of some type can be converted to a value of
some other type.

> Does C (whatever standard) allow the type of a variable to change,
> within a statement, avoiding the conversion? And if so, provide an
> example of how its done.
>
> Example:
> int a=23;
> int b=34;
> char c='a';
> int * p_int=(int *)&c;
>

A few concerns with that last line including "alignment issues, storage
size issues, etc."

> // type casting
> // c is converted into type integer, then b is added.
> (int) c + b;
>

I don't think so. The value of 'c' is converted to an 'int' value, that
is added to the value of 'b', then the result is unused. 'c' remains a
'char' throughout.

> //retypeing
> (type int) c + b;

What is 'type'? It's not a C keyword. Is it some macro you haven't shared?

> // similar action
> *p_int + b
>

Assuming the original initialization of 'p_int' succeeded and still
points to the first byte of the object identified as 'c', the expression
'*p_int' attempts to re-interpret the bytes at the address of 'c' as an
object representation for an 'int' value.

> Ignoring alignment issues, storage size issues, etc., c is retyped to
> an integer, no conversion is done, and c is used, within the
> statement, as an integer, not a char.

You can do similar things with unions for re-interpreting an object
representation of a value of one type as an object representation of a
value of a different type.

I don't understand why one would wish to ignore alignment issues,
storage size issues, etc.

To answer the only question in this post, you might be interested in C's
definition of "effective type." For example, in:

void * vp = malloc(sizeof (int[10]);

if 'malloc' succeeds, the object pointed to by 'vp' has no declared type
and no effective type. An effective type can later be established by
using an lvalue to read or modify the object.

int (* ten_ints)[10] = vp;

if (ten_ints) {
(*ten_ints)[0] = 1;
/* ... */
(*ten_ints)[9] = 10;
}

Now the effective type for the allocate storage has been established as
the type 'int[10]'.

Shao Miller

7/1/2011 11:41:00 PM

0

On 7/1/2011 5:13 PM, Rich Touper wrote:
> On Fri, 01 Jul 2011 17:52:35 -0500, Shao Miller wrote:
>> On 7/1/2011 4:21 PM, Rich Touper wrote:
>>> C allows type casting in which a variable is converted from one type to
>>> another.
>
> As everyone pointed out, "converted" should be "promoted", and "during
> evaluation" should have been tacked on the end. That would have helped
> on the semantics of the question, but is still vague.
>
>> Hmm... Not that I know of. As far as I know, there isn't any "type
>> casting" in C, but a value of some type can be converted to a value of
>> some other type.
>
> That seems to be the concensus of opinion. I certainly never heard of
> it, but thought it may be an obscure, rarely used feature.
>
>>> Does C (whatever standard) allow the type of a variable to change,
>>> within a statement, avoiding the conversion? And if so, provide an
>>> example of how its done.
>>>
>>> Example:
>>> int a=23;
>>> int b=34;
>>> char c='a';
>>> int * p_int=(int *)&c;
>>>
>>>
>> A few concerns with that last line including "alignment issues, storage
>> size issues, etc."
>
> Wasn't attempting to start a huge thread on pointers, just using it to
> illustrate a point.
>
>>> // type casting
>>> // c is converted into type integer, then b is added. (int) c + b;
>>>
>>>
>> I don't think so. The value of 'c' is converted to an 'int' value, that
>> is added to the value of 'b', then the result is unused. 'c' remains a
>> 'char' throughout.
>
> Exactly. The pomotion happens according to the standard, but only the
> value of c is used, and because c is type char, 1 byte.
>

Promotion is due to rank. 'char' has a rank less than 'int' (and
'unsigned int' and 'signed int'). Rank is not the same as size.

>>> //retypeing
>>> (type int) c + b;
>>
>> What is 'type'? It's not a C keyword. Is it some macro you haven't
>> shared?
>
> I don't have a way to define it. But the point is IF c could be "retyped"
> to an int, then sizeof(int) bytes would be used during evaluation. As
> other posters pointed out, there would be alignment issues, unknown bytes
> at&c+1 to&c+sizeof(int), etc...
>
> I'll take this as a resounding NO. No such thing as "retyping".

Well for C99 and "simple types" (those that can be declared like "type
id")...

#define RETYPE(from_type, to_type, value) ( \
(union { from_type from; to_type to; }) \
{ .from = (value) } \
.to \
)

You can always 'typedef' "complicated types" to "simple types" and use
this macro.

I'm not sure that I fully understand the inquiry/discussion. An
implementation doesn't have to use 'sizeof (int)' bytes at any time
during evaluation, as far as I know.

If you wish to reinterpret an object representation as another type,
unions are handy.

union char_and_int {
unsigned char bytes[sizeof (int)];
char c;
int i;
};

/* First member 'bytes' initialized to zero bytes */
union char_and_int foo = { { 0 } };

/* Member 'c' set to '5' */
foo.c = 5;
/* Now you can work with 'foo.i' */

(But 'foo.i' might be a trap representation.)

Shao Miller

7/1/2011 11:49:00 PM

0

On 7/1/2011 6:40 PM, Shao Miller wrote:
>
> If you wish to reinterpret an object representation as another type,
> unions are handy.
>
> union char_and_int {
> unsigned char bytes[sizeof (int)];
> char c;
> int i;
> };
>
> /* First member 'bytes' initialized to zero bytes */
> union char_and_int foo = { { 0 } };
>
> /* Member 'c' set to '5' */
> foo.c = 5;
> /* Now you can work with 'foo.i' */
>
> (But 'foo.i' might be a trap representation.)

I should add that 'foo.i' isn't necessarily '5', either.

Eric Sosman

7/2/2011 1:48:00 AM

0

On 7/1/2011 5:21 PM, Rich Touper wrote:
> C allows type casting in which a variable is converted from one type
> to another.

No. C allows casting (not "type casting") in which a value
(not a "variable") is converted from one type to another.

> Does C (whatever standard) allow the type of a variable to change,
> within a statement, avoiding the conversion? And if so, provide an
> example of how its done.

Every C expression has a type, determined at compile time and
immutable thereafter. A variable (in suitable context) is an
expression, albeit a rather simple one. A variable, once declared,
has an immutable type and there's nothing you can do to change it
short of editing the source code.

> Example:
> int a=23;
> int b=34;
> char c='a';
> int * p_int=(int *)&c;
>
> // type casting
> // c is converted into type integer, then b is added.
> (int) c + b;

The *value* of `c' is converted to the type int and then
the value of `b' is added. `c' is still of type `char'.

> //retypeing
> (type int) c + b;
> // similar action
> *p_int + b

Sorry; I'm unable to fathom your meaning here.

> Ignoring alignment issues, storage size issues, etc., c is retyped to
> an integer, no conversion is done, and c is used, within the
> statement, as an integer, not a char.

Ditto.

--
Eric Sosman
esosman@ieee-dot-org.invalid

gordonb.x5p62

7/2/2011 2:08:00 AM

0

> C allows type casting in which a variable is converted from one type
> to another.

What you are describing is "casting". Type casting is done in Hollywood.
There are also implicit conversions done in evaluating expressions.

> Does C (whatever standard) allow the type of a variable to change,
> within a statement, avoiding the conversion?

C considers that to *be* a conversion. A conversion need not generate
extra code. For example, if int and long are both 32-bit signed integers,
a cast from int to long is still a conversion. It shouldn't generate
extra any code, though.

It is impossible to avoid a conversion that actually *does* something
if the old type and the new type have different sizes. At a minimum,
you ignore part of the old variable, zero-extend it, sign-extend
it, or perhaps garbage-extend it, which might be doable as part of
a "load register" instruction, so it still might appear to be done
in 0 instructions.

> And if so, provide an
> example of how its done.
>
> Example:
> int a=23;
> int b=34;
> char c='a';
> int * p_int=(int *) &c;
>
> // type casting
> // c is converted into type integer, then b is added.
> (int) c + b;
>
> //retypeing
> (type int) c + b;
> // similar action
> *p_int + b
>
> Ignoring alignment issues,

I take that to mean "if it goes *KABOOM*, let it go *KABOOM*".
If you don't care what the result is, what possible good is it?

> storage size issues, etc., c is retyped to
> an integer, no conversion is done, and c is used, within the
> statement, as an integer, not a char.

In other words, use random crap. What problem are you attempting
to solve?

What noticible effect is there between using a cast and what you
call "retypeing", except that "retypeing" may produce a garbage
value and casting is a bit more controlled as to when it produces
undefined behavior? What's the practical difference between this
and
*((char *) rand()) = rand();

which always generates undefined behavior?

Eric Sosman

7/2/2011 2:33:00 AM

0

On 7/1/2011 6:13 PM, Rich Touper wrote:
> On Fri, 01 Jul 2011 17:52:35 -0500, Shao Miller wrote:
>> On 7/1/2011 4:21 PM, Rich Touper wrote:
>>> C allows type casting in which a variable is converted from one type to
>>> another.
>
> As everyone pointed out, "converted" should be "promoted", and "during
> evaluation" should have been tacked on the end. That would have helped
> on the semantics of the question, but is still vague.

Still wrong, too. Promotions are a subset of conversions, not a
superset. Some conversions performed by casts are not promotions at
all: `(short)42' for example.

>>> // type casting
>>> // c is converted into type integer, then b is added. (int) c + b;
>>>
>>>
>> I don't think so. The value of 'c' is converted to an 'int' value, that
>> is added to the value of 'b', then the result is unused. 'c' remains a
>> 'char' throughout.
>
> Exactly. The pomotion happens according to the standard, but only the
> value of c is used, and because c is type char, 1 byte.

I see no promotions at all in `(int)c + b'. There is an explicit
conversion of the value of `c' to type `int', and the addition of the
value of `b' (also of type `int', in the snippage). On an "exotic"
system with CHAR_MAX > INT_MAX, the char-to-int conversion could in
fact be a "demotion."

>>> //retypeing
>>> (type int) c + b;
>>
>> What is 'type'? It's not a C keyword. Is it some macro you haven't
>> shared?
>
> I don't have a way to define it. But the point is IF c could be "retyped"
> to an int, then sizeof(int) bytes would be used during evaluation. As
> other posters pointed out, there would be alignment issues, unknown bytes
> at&c+1 to&c+sizeof(int), etc...

Your intent is still unclear to me, but I begin to suspect you
have confused representation with value. C doesn't compute with
bytes and bits, but with the values those bytes and bits represent.
You may think a `char' is eight bits, but how wide is it when it's
been loaded into a 64-bit CPU register? The value is what matters.

(Usually, at any rate, and certainly in the examples you've
shown. Representation arises in a few cases: For example, it is
always permitted to manipulate an object's storage as an array of
bytes. For operators like `+' and `(type)' it's all about value.)

--
Eric Sosman
esosman@ieee-dot-org.invalid