Terminology : casting/conversion

R

Richard G. Riley

Would it be wrong to use "implicit casting" instead of the standards
"implicit conversion" when talking about implicit conversions between
certain data types. The standard mentions "explicit conversion" for a
cast operation
 
R

Robert Gamble

Richard said:
Would it be wrong to use "implicit casting" instead of the standards
"implicit conversion" when talking about implicit conversions between
certain data types. The standard mentions "explicit conversion" for a
cast operation

If a cast is an explicit conversion then an "implicit cast" would be an
implicit explicit conversion, does that make much sense to you?

Robert Gamble
 
C

Chris Torek

Would it be wrong to use "implicit casting" instead of the standards
"implicit conversion" when talking about implicit conversions between
certain data types.

It is certainly more consistent (and I think much less misleading)
to use the phrase "implicit conversion". This is because the C
standard defines "cast" as, in effect, "the syntactic construct
consisting of a parenthesized type-name followed by a value
expression, which causes an explicit conversion".

The "followed by a value" part is to handle C99's aggregate constants,
which use remarkably similar syntax, except that the parenthesized
type-name is followed by an open brace. That is:

(int)3.14159

uses a cast, but:

(int []){ 3, 1, 4, 1, 5, 9 }

does not -- the parenthesized type supplies the information needed
to construct the correct aggregate type, here "array 6 of int".
Note that the same sequence of six "int" constants might be used
to initialize something that is not an array at all:

struct zorg {
char a;
double b;
short c;
long d;
float e;
int f;
};
...
(struct zorg){ 3, 1, 4, 1, 5, 9 }

If a "cast" is nothing more than the explicit syntactic construct,
an "implicit cast" must be an "implicit explicit syntactic construct":
oxymoronic, like "large small" or "jumbo shrimp". :)

(The last line above is meant more to point out that such things
do exist in English, and it would be possible for the C Standard
to define the phrase "implicit cast" as an alternative for "implicit
conversion". But it does not, and there is no need to clutter
one's vocabulary with Extra Alternative Options from the Bureau of
Redundancy Department.)
 
M

Michael Mair

Richard said:
Would it be wrong to use "implicit casting" instead of the standards
"implicit conversion" when talking about implicit conversions between
certain data types. The standard mentions "explicit conversion" for a
cast operation

In my understanding: Yes. C99, 6.3#1 speaks of operand value
type conversions taking place automatically as implicit
conversions -- which are opposed to casts (which are explicit
conversions).
An "implicit cast" makes no sense as it cannot be a cast.

Cheers
Michael
 
R

Richard G. Riley

Would it be wrong to use "implicit casting" instead of the standards
"implicit conversion" when talking about implicit conversions between
certain data types.

It is certainly more consistent (and I think much less misleading)
to use the phrase "implicit conversion". This is because the C
standard defines "cast" as, in effect, "the syntactic construct
consisting of a parenthesized type-name followed by a value
expression, which causes an explicit conversion".

The "followed by a value" part is to handle C99's aggregate constants,
which use remarkably similar syntax, except that the parenthesized
type-name is followed by an open brace. That is:

(int)3.14159

uses a cast, but:

(int []){ 3, 1, 4, 1, 5, 9 }

does not -- the parenthesized type supplies the information needed
to construct the correct aggregate type, here "array 6 of int".
Note that the same sequence of six "int" constants might be used
to initialize something that is not an array at all:

struct zorg {
char a;
double b;
short c;
long d;
float e;
int f;
};
...
(struct zorg){ 3, 1, 4, 1, 5, 9 }

If a "cast" is nothing more than the explicit syntactic construct,
an "implicit cast" must be an "implicit explicit syntactic construct":
oxymoronic, like "large small" or "jumbo shrimp". :)

(The last line above is meant more to point out that such things
do exist in English, and it would be possible for the C Standard
to define the phrase "implicit cast" as an alternative for "implicit
conversion". But it does not, and there is no need to clutter
one's vocabulary with Extra Alternative Options from the Bureau of
Redundancy Department.)


thanks for the replies guys.
 
R

Richard G. Riley

In my understanding: Yes. C99, 6.3#1 speaks of operand value
type conversions taking place automatically as implicit
conversions -- which are opposed to casts (which are explicit
conversions).
An "implicit cast" makes no sense as it cannot be a cast.

I see that, but in my twisted logic I guess that if its not an
explicit cast but a conversion is being done "implicitly" then its an
implicit cast ... ie same result but without the cast : or is that
where I'm making my mistake? The result is not the same? I could be
just confusing myself here : it has been known..
 
R

Richard Heathfield

Richard G. Riley said:
I see that, but in my twisted logic I guess that if its not an
explicit cast

Whoops - an "explicit cast" would be an "explicit explicit conversion".
but a conversion is being done "implicitly" then its an
implicit cast

i.e. an "implicit explicit conversion", which, as Chris pointed out, is
oxymoronic.
 
R

Richard G. Riley

Richard G. Riley said:


Whoops - an "explicit cast" would be an "explicit explicit conversion".

Richard, lets stick with this because I'm really confused here : no
shit.

If I do

p = (char *)p2;

Is this an "explicit" cast? Or just a cast?

p = p2;

Here are p & p2 are pointers but the compiler "implicitly" converts
one to the other since they are different base pointer types.

Now to my really confused mind, it would be ok to call this an
"implicit cast"?

To be honest I never really gave it much thought before, but soon
realised that if one is to joing in the mud slinging then ones
vocabulary has to be spot on.
 
C

Chris Torek

If I do

p = (char *)p2;

Is this an "explicit" cast? Or just a cast?

I would call it just "a cast". Specifically, the cast (or
"cast expression" or "cast-expression") is the part on the right
hand side of the assigment. From a C99 draft:

6.3.4 Cast operators

Syntax

[#1]

cast-expr:
unary-expr
( type-name ) cast-expr
...
Semantics

[#4] Preceding an expression by a parenthesized type name
converts the value of the expression to the named type.
This construction is called a cast.73 A cast that specifies
no conversion has no effect on the type or value of an
expression.74

__________

73. A cast does not yield an lvalue. Thus, a cast to a
qualified type has the same effect as a cast to the
unqualified version of the type.

74. If the value of the expression is represented with
greater precision or range than required by the type
named by the cast (6.2.1.7), then the cast specifies a
conversion even if the type of the expression is the
same as the named type.


I will note that the phrase "explicit cast" *does* appear in the
(draft) Standard, right in the section I elided above:

Constraints

[#2] Unless the type name specifies a void type, the type
name shall specify qualified or unqualified scalar type and
the operand shall have scalar type.

[#3] Conversions that involve pointers, other than where
permitted by the constraints of 6.3.16.1, shall be specified
by means of an explicit cast.

However, this is the only occurrence of that phrase, and it appears
after the following:

6.2 Conversions

[#1] Several operators convert operand values from one type
to another automatically. This subclause specifies the
result required from such an implicit conversion, as well as
those that result from a cast operation (an explicit
conversion). The list in 6.2.1.7 summarizes the conversions
performed by most ordinary operators; it is supplemented as
required by the discussion of each operator in 6.3.

[#2] Conversion of an operand value to a compatible type
causes no change to the value or the representation.

Paragraph #1 here makes it clear that a cast is an explicit
conversion, and there are other kinds of conversions that are
implicit.
p = p2;

Here are p & p2 are pointers but the compiler "implicitly" converts
one to the other since they are different base pointer types.

You need to show declarations (or at least those base types) first,
here. :)

To make it "work right" let me supply them now, along with the rest
of the original code:

char *p;
void *p2;
... /* presumably this code sets p2 */
p = (char *)p2;
...
p = p2;

Both assignments are now correct. There is only one cast, on the
right hand side of the first ordinary assignment operator.
Now to my really confused mind, it would be ok to call [the
second expression] an "implicit cast"?

I think it is much better to use the phrase "implicit conversion"
(in this case, from "void *" to "char *"). Reserve the word "cast"
to refer only to the syntactic (source-code) construct.

(I do not know if you have ever worked on the "compiler geek" side
of the computer, but if you have -- or if you can recall the
appropriate college courses -- you might note that modern compilers
generally comprise a number of loosely, or at least not overly
tightly, coupled pieces. One or two front end parts break up the
input into "lexemes" or "tokens" that can be recognized by simple
regular expressions. These feed into a "parser" that turns
syntactically-correct "sentences" into, typically, a "parse tree".
In a toy compiler, this parse tree is almost unconnected to the
original source, although in real compilers the tree is highly
decorated so that each piece can be tracked back to the appropriate
source line or even character, both for error messsages -- which
need to refer you back to the source code -- and for associating
final machine instructions with source code for the debuggers.

The parse tree is then manipulated by a semantic analyzer that
replaces the original tree with something equivalent. Semantics
analysis is where most optimization occurs. Consider the following
C parse tree fragment:

(LIST
(ASSIGN (VAR sum) (DOUBLECONST 0.0))
(ASSIGN (VAR i) (INTCONST 0))
(LOOP-WHILE (LESS-THAN (VAR i) (INTCONST 10))
(ASSIGN (VAR sum)
(PLUS (VAR sum)
(DEREF
(PLUS (ADDR arr)
(TIMES (VAR i) (INTCONST 8))))))
(ASSIGN (var i) (PLUS (VAR i) (INTCONST 1))))
)

This parse tree might arise out of the source code:

sum = 0.0;
for (i = 0; i < 10; i++)
sum += arr;

where "sum" is a double and "i" is an int. The "INTCONST 8" is
simply the size of a double, and the DEREF nodes occur because
arr "means" *(arr + i), so the syntactic front-end handler simply
generates a (DEREF (PLUS ...)) node in every case.

The semantic analyzer's job includes discovering that the variable
"i" is not used after the loop, so the loop can -- if this is
profitable -- be strength-reduced to eliminate the embedded
multiply:

(LOOP-WHILE (LESS-THAN (VAR i) (INTCONST 80))
(ASSIGN (VAR sum)
(PLUS (VAR sum)
(DEREF
(PLUS (ADDR arr) (VAR i)))))
(ASSIGN (var i) (PLUS (VAR i) (INTCONST 8))))

This loop is equivalent if and only if "i" is dead after this point.
If not, the strength-reduction can still be done by rewriting each
(VAR i) with (VAR i2), where i2 is created by the compiler, and
adding a final (ASSIGN (VAR i) 10) after the loop. [Depending on
the compiler, the strength-reducer may simply automatically insert
a new variable, and let later dead-code optimization remove the
unneeded one(s).]

Following -- or in some, hairier compilers, intermingled with --
semantic analysis and overall high-level optimization, the compiler
must do instruction selection/generation and scheduling. On
modern CPUs, instruction scheduling is just as hard a problem
as semantic analysis, and the selection and generation do affect
which optimizations are appropriate, so this is basically where
all the money is. :)

On the compiler-geek side, syntax is "mere" syntax: the Lisp-like
parse tree above is just as good as the C fragment, and in many
cases quite preferable. Of course, not all humans feel the same
way about "mere" syntax. A spoonful of "syntactic sugar" often
seems to help the medicine go down.)
 
E

Eric Sosman

Richard said:
If I do

p = (char *)p2;

Is this an "explicit" cast? Or just a cast?

It is a "cast," and it is "explicit," but "explicit cast"
is overkill. In `a + b' would you call the `+' an "explicit
addition operator?"
p = p2;

Here are p & p2 are pointers but the compiler "implicitly" converts
one to the other since they are different base pointer types.

Assuming that they're assignment-compatible; if `p' is
a `double*' and `p2' is a `char*', this would require a
diagnostic. But yes: If they're something like `double*'
and `void*', the conversion is implicit.
Now to my really confused mind, it would be ok to call this an
"implicit cast"?

No; there's no such thing. It's an implicit conversion,
that is, a conversion that occurs in the absence of an operator
(all operators are explicit).

I think that you (and you're not by any means alone) have
somehow stirred the two different notions of "conversion" and
"cast" into the same can of muddy-colored paint. If you make
a point of separating them:

- A "conversion" is the act of deriving a value of one type
from a value of another. Some conversions (`int' -> `long',
`char*' -> `void*', others) occur automatically when the
context requires them; these are "implicit" conversions.

- A "cast" is an operator that causes a conversion (except
in degenerate cases like casting an `int' to an `int', or
casting anything to `void'). Since it is written out in
the source code, right there where anyone can see it, it
is necessarily "explicit."

.... your confusion may diminish.

A single expression can have both implicit and explicit
conversions, e.g. `(double)5 / 9': the conversion of five from
`int' to `double' is explicit and caused by the cast, while
the conversion of nine from `int' to `double' is implicit,
implied by the rules of the division operator. And, of course,
an expression can also have unnecessary explicit conversions,
as in `(double)5 / (double)9' -- there can be sometimes be
value in inserting extra casts as a kind of documentation.
 
R

Richard G. Riley

I think that you (and you're not by any means alone) have
somehow stirred the two different notions of "conversion" and

I think you're right and in over 15 years of programming this is the
first time I ever really considered the words : it was someone calling
me an idiot somewhere for using the wrong word which woke me up :)
"cast" into the same can of muddy-colored paint. If you make
a point of separating them:

- A "conversion" is the act of deriving a value of one type
from a value of another. Some conversions (`int' -> `long',
`char*' -> `void*', others) occur automatically when the
context requires them; these are "implicit" conversions.

- A "cast" is an operator that causes a conversion (except
in degenerate cases like casting an `int' to an `int', or
casting anything to `void'). Since it is written out in
the source code, right there where anyone can see it, it
is necessarily "explicit."

... your confusion may diminish.

It is, but ... (please stick with me) ... there are cases where "casts
are not required" because of an implicit conversion? This is right,
yes?

A single expression can have both implicit and explicit
conversions, e.g. `(double)5 / 9': the conversion of five from
`int' to `double' is explicit and caused by the cast, while

"The cast causes an explicit conversion"?. Fine.
the conversion of nine from `int' to `double' is implicit,
implied by the rules of the division operator. And, of course,
an expression can also have unnecessary explicit conversions,
as in `(double)5 / (double)9' -- there can be sometimes be
value in inserting extra casts as a kind of documentation.

Thanks Eric : nothing I didnt "know" in practice, but now the terminology is
clearer : for now :-; Funny how as you stay away from academic
reasoners the vocab slips so bad :( Before you know it I'll be calling
pointers "references" ...
 
R

Richard G. Riley

Thaks Chris : you & Eric have cleared it up. There was a piece of crud
stuck to my cerebral cortex which your explanations dissolved :) Uni
was over 15 years ago too : so proper terminology might have, cough,
suffered a little.


If I do

p = (char *)p2;

Is this an "explicit" cast? Or just a cast?

I would call it just "a cast". Specifically, the cast (or
"cast expression" or "cast-expression") is the part on the right
hand side of the assigment. From a C99 draft:

6.3.4 Cast operators

Syntax

[#1]

cast-expr:
unary-expr
( type-name ) cast-expr
...
Semantics

[#4] Preceding an expression by a parenthesized type name
converts the value of the expression to the named type.
This construction is called a cast.73 A cast that specifies
no conversion has no effect on the type or value of an
expression.74

__________

73. A cast does not yield an lvalue. Thus, a cast to a
qualified type has the same effect as a cast to the
unqualified version of the type.

74. If the value of the expression is represented with
greater precision or range than required by the type
named by the cast (6.2.1.7), then the cast specifies a
conversion even if the type of the expression is the
same as the named type.


I will note that the phrase "explicit cast" *does* appear in the
(draft) Standard, right in the section I elided above:

Constraints

[#2] Unless the type name specifies a void type, the type
name shall specify qualified or unqualified scalar type and
the operand shall have scalar type.

[#3] Conversions that involve pointers, other than where
permitted by the constraints of 6.3.16.1, shall be specified
by means of an explicit cast.

However, this is the only occurrence of that phrase, and it appears
after the following:

6.2 Conversions

[#1] Several operators convert operand values from one type
to another automatically. This subclause specifies the
result required from such an implicit conversion, as well as
those that result from a cast operation (an explicit
conversion). The list in 6.2.1.7 summarizes the conversions
performed by most ordinary operators; it is supplemented as
required by the discussion of each operator in 6.3.

[#2] Conversion of an operand value to a compatible type
causes no change to the value or the representation.

Paragraph #1 here makes it clear that a cast is an explicit
conversion, and there are other kinds of conversions that are
implicit.
p = p2;

Here are p & p2 are pointers but the compiler "implicitly" converts
one to the other since they are different base pointer types.

You need to show declarations (or at least those base types) first,
here. :)

To make it "work right" let me supply them now, along with the rest
of the original code:

char *p;
void *p2;
... /* presumably this code sets p2 */
p = (char *)p2;
...
p = p2;

Both assignments are now correct. There is only one cast, on the
right hand side of the first ordinary assignment operator.
Now to my really confused mind, it would be ok to call [the
second expression] an "implicit cast"?

I think it is much better to use the phrase "implicit conversion"
(in this case, from "void *" to "char *"). Reserve the word "cast"
to refer only to the syntactic (source-code) construct.

(I do not know if you have ever worked on the "compiler geek" side
of the computer, but if you have -- or if you can recall the
appropriate college courses -- you might note that modern compilers
generally comprise a number of loosely, or at least not overly
tightly, coupled pieces. One or two front end parts break up the
input into "lexemes" or "tokens" that can be recognized by simple
regular expressions. These feed into a "parser" that turns
syntactically-correct "sentences" into, typically, a "parse tree".
In a toy compiler, this parse tree is almost unconnected to the
original source, although in real compilers the tree is highly
decorated so that each piece can be tracked back to the appropriate
source line or even character, both for error messsages -- which
need to refer you back to the source code -- and for associating
final machine instructions with source code for the debuggers.

The parse tree is then manipulated by a semantic analyzer that
replaces the original tree with something equivalent. Semantics
analysis is where most optimization occurs. Consider the following
C parse tree fragment:

(LIST
(ASSIGN (VAR sum) (DOUBLECONST 0.0))
(ASSIGN (VAR i) (INTCONST 0))
(LOOP-WHILE (LESS-THAN (VAR i) (INTCONST 10))
(ASSIGN (VAR sum)
(PLUS (VAR sum)
(DEREF
(PLUS (ADDR arr)
(TIMES (VAR i) (INTCONST 8))))))
(ASSIGN (var i) (PLUS (VAR i) (INTCONST 1))))
)

This parse tree might arise out of the source code:

sum = 0.0;
for (i = 0; i < 10; i++)
sum += arr;

where "sum" is a double and "i" is an int. The "INTCONST 8" is
simply the size of a double, and the DEREF nodes occur because
arr "means" *(arr + i), so the syntactic front-end handler simply
generates a (DEREF (PLUS ...)) node in every case.

The semantic analyzer's job includes discovering that the variable
"i" is not used after the loop, so the loop can -- if this is
profitable -- be strength-reduced to eliminate the embedded
multiply:

(LOOP-WHILE (LESS-THAN (VAR i) (INTCONST 80))
(ASSIGN (VAR sum)
(PLUS (VAR sum)
(DEREF
(PLUS (ADDR arr) (VAR i)))))
(ASSIGN (var i) (PLUS (VAR i) (INTCONST 8))))

This loop is equivalent if and only if "i" is dead after this point.
If not, the strength-reduction can still be done by rewriting each
(VAR i) with (VAR i2), where i2 is created by the compiler, and
adding a final (ASSIGN (VAR i) 10) after the loop. [Depending on
the compiler, the strength-reducer may simply automatically insert
a new variable, and let later dead-code optimization remove the
unneeded one(s).]

Following -- or in some, hairier compilers, intermingled with --
semantic analysis and overall high-level optimization, the compiler
must do instruction selection/generation and scheduling. On
modern CPUs, instruction scheduling is just as hard a problem
as semantic analysis, and the selection and generation do affect
which optimizations are appropriate, so this is basically where
all the money is. :)

On the compiler-geek side, syntax is "mere" syntax: the Lisp-like
parse tree above is just as good as the C fragment, and in many
cases quite preferable. Of course, not all humans feel the same
way about "mere" syntax. A spoonful of "syntactic sugar" often
seems to help the medicine go down.)
 
E

Eric Sosman

Richard said:
It is, but ... (please stick with me) ... there are cases where "casts
are not required" because of an implicit conversion? This is right,
yes?

Yes: Sometimes the conversion called for by a cast is the
same one the compiler would have done implicitly had the cast
been absent:

long l;
l = 42; /* implicit int => long */
l = (long)42; /* explicit int => long */
Thanks Eric : nothing I didnt "know" in practice, but now the terminology is
clearer : for now :-; Funny how as you stay away from academic
reasoners the vocab slips so bad :( Before you know it I'll be calling
pointers "references" ...

If you want That Other Language, you know where to find it. ;-)

A certain looseness of language can be useful at times, as
it can condense long-winded descriptions into brief phrases that
don't interrupt the flow of thought. We say that the argument to
strlen() is a "pointer to a string," which is more convenient
than saying it is a "pointer to a char somewhere in an array
containing a zero-valued char at or after the pointed-to char."
We speak of a pointer that points "just past the end of an array,"
which you may wish to contrast with the Standard's long-winded
prose that describes the properties of that pointer without using
the troublesome notion of the existence of a "one past the end"
element. We speak of the limit of f(x) "as x approaches x0,"
rather than use the long-winded epsilons and deltas of a calculus
text, which carefully defines "limit" without appealing to ideas
of "motion."

Convenient as loose speech can be, sometimes greater precision
is required -- as, for example, when someone is asking about the
fine distinctions! (And sometimes someone who seems to be speaking
precisely is not in fact doing so. At the closing for a house
purchase, the bank's lawyer asked to "see" my check for the down
payment. I passed it to him, and the ritual proceeded. Some time
later as he got ready to leave, he asked if there were any questions.
"One," said I. "Did you want me to sign that check?" He had used
the brief and inexact "Let me see the check" instead of "Sign the
check and give it to me in the presence of these witnesses," and
what with me being a first-time buyer and him being a professional
I had assumed he was speaking precisely. It would have been nice
to buy the house for a Whole Lot Less than the agreed price, but even
as a first-time buyer I had a hunch I wouldn't get away with it ...)
 
R

Richard Bos

Richard G. Riley said:
Would it be wrong to use "implicit casting" instead of the standards
"implicit conversion" when talking about implicit conversions between
certain data types. The standard mentions "explicit conversion" for a
cast operation

It's about as right as using "implicit right turn sign" for a bend in
the road.

Richard
 
R

Richard Bos

Oh, bull.
Richard, lets stick with this because I'm really confused here : no
shit.

If I do

p = (char *)p2;

Is this an "explicit" cast? Or just a cast?

It is a cast. Since a cast is a source code construct, _all_ casts are
explicit. Calling it an explicit cast is therefore redundant, but not
actually wrong.
p = p2;

Here are p & p2 are pointers but the compiler "implicitly" converts
one to the other since they are different base pointer types.

Now to my really confused mind, it would be ok to call this an
"implicit cast"?

No. It's a conversion. There is no (type) in the code, so there is no
cast, implicit or otherwise.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top