C++ casts

A

Alf P. Steinbach

* Jacob:
It is a common recommendation to use
"static_cast<SomeType> someInstance" instead of the
traditional infamous "(SomeType) someInstance".

Should I use the same practice for simple types,
i.e. instead of:

double fraction = (double) n / total;

should I write this?

double fraction = static_cast<double>(n) /
static_cast<double>(total);

I find the traditional version a lot more readable
in this case.

There are at least three reasons why it's a Good Idea (TM) to use the C++
named casts also for simple built-in types:

* It helps you and maintainers of your code remember to not use C-style
casts in general, which can help to prevent accidental usage.

* C-style casts can do const_cast and reinterpret_cast, which you probably
don't want (especially not for pointer values).

* The type definitions may be changed when the code is maintained.
 
J

Jacob

It is a common recommendation to use
"static_cast<SomeType> someInstance" instead of the
traditional infamous "(SomeType) someInstance".

Should I use the same practice for simple types,
i.e. instead of:

double fraction = (double) n / total;

should I write this?

double fraction = static_cast<double>(n) /
static_cast<double>(total);

I find the traditional version a lot more readable
in this case.

Thanks!
 
B

benben

Jacob said:
It is a common recommendation to use
"static_cast<SomeType> someInstance" instead of the
traditional infamous "(SomeType) someInstance".

Should I use the same practice for simple types,
i.e. instead of:

double fraction = (double) n / total;

should I write this?

double fraction = static_cast<double>(n) /
static_cast<double>(total);

I find the traditional version a lot more readable
in this case.

This is TRUE! The traditional version DOES feel a lot natural than the C++
new cast operators.

But this is EXACTLY why C++ cast operators look this way: they are so ugly
looking to discourage you and alert you from using them. And you can always
pick up all casts using a find in a text editor.
 
P

pookiebearbottom

Is the equivilent of
double fraction = (double) n / total;
really
double fraction = static_cast<double>(n) / total;

double fraction = (double) n / (double) total;

isn't that readable either
 
G

Greg

Jacob said:
It is a common recommendation to use
"static_cast<SomeType> someInstance" instead of the
traditional infamous "(SomeType) someInstance".

Should I use the same practice for simple types,
i.e. instead of:

double fraction = (double) n / total;

should I write this?

double fraction = static_cast<double>(n) /
static_cast<double>(total);

I find the traditional version a lot more readable
in this case.

You should avoid casts altogether and write it the C++ way:

double fraction = double(n) / double(total);

assuming that n and total are both a scalar value type convertible to a
double.

Greg
 
A

Alf P. Steinbach

* Jacob:
This is not "the C++ way": using C casts is the way of C programmers.

I like this.

It's C-style casts, expressed in C++ functional notation.

'T(v)' is equivalent to '(T)v'.

I did search for backing on this syntax
originally but neither S. Meyers nor A. Sutter mentions
it. And my colleges didn't knew about it.

Could you please back it with some links?

§5.2.3/1.
 
J

Jacob

benben said:
But this is EXACTLY why C++ cast operators look this way: they are so ugly
looking to discourage you and alert you from using them. And you can always
pick up all casts using a find in a text editor.

So did they really invent this ugly syntax so I
shouldn't use casting, or is this just an urban
myth?

I'd guess there are people from academia telling you
not to cast ever, but no industry scale C++ system
can do without it. And how can I find the fraction of
int 10 to int 35 without casting?

And why do I need a syntax so that _Notepad_ can tell
me where my casts are? First, I wouldn't categorize
code by casts (I don't need a way to find them all),
and a _proper_ editor would tell me (if asked) anyway.

Isn't it so that static_cast (and its cousins) is an
aid for the compiler to to proper type checking and
that neither the compiler nor the runtime environment
can help me when trying to find the fraction of two
integers?

Thanks!
 
P

peter.koch.larsen

Jacob skrev:
So did they really invent this ugly syntax so I
shouldn't use casting, or is this just an urban
myth?

I heard that reinterpret_cast was made purposefully ackward to
discourage its use.
I'd guess there are people from academia telling you
not to cast ever, but no industry scale C++ system
can do without it. And how can I find the fraction of
int 10 to int 35 without casting?

I doubt any from academia would tell you never to cast, but casting the
C++ way really is much better. Casting in C++ is much rarer than in C,
however.
And why do I need a syntax so that _Notepad_ can tell
me where my casts are? First, I wouldn't categorize
code by casts (I don't need a way to find them all),
and a _proper_ editor would tell me (if asked) anyway.

Well, finding casts is not easy when you use C-syntax. But the primary
raison d'etre for the new casts is that you tell precisely what kind of
cast you're performing.
Isn't it so that static_cast (and its cousins) is an
aid for the compiler to to proper type checking and
that neither the compiler nor the runtime environment
can help me when trying to find the fraction of two
integers?

There is no aid whatsoever to the compiler. There's a huge aid to the
reader of your code - yourself a half year later or one of your
collegues. A traditional C-style cast does not tell you anything, and
you do cast away const amongst other things. Don't use them.

/Peter
 
J

Jacob

Greg said:
You should avoid casts altogether and write it the C++ way:

double fraction = double(n) / double(total);

assuming that n and total are both a scalar value type convertible to a
double.

I like this. I did search for backing on this syntax
originally but neither S. Meyers nor A. Sutter mentions
it. And my colleges didn't knew about it.

Could you please back it with some links?

Thanks!
 
D

Default User

Greg said:
You should avoid casts altogether and write it the C++ way:

double fraction = double(n) / double(total);

assuming that n and total are both a scalar value type convertible to
a double.


I think that's even worse. It's very difficult to search for those, and
it's less obvious at a glance that casting is going on.




Brian
 
G

Greg

Alf said:
* Jacob:

This is not "the C++ way": using C casts is the way of C programmers.



It's C-style casts, expressed in C++ functional notation.

'T(v)' is equivalent to '(T)v'.



§5.2.3/1.

The expression double(n) is uniquely C++ both syntactically and
conceptually since it "constructs" the double value by converting n:

A simple-type-specifier (dcl.type) followed by a parenthesized
expression-list constructs a value of the specified type given
the expression list. (5.2.3.1)

And in fact replacing "double" with the name of a class that has a
single parameter constuctor would not change the meaning of the
expression at all - only the type of the value constructed would
differ. The advantage here is that the syntax for constructing built-in
types is made compatible with constructing user-defined types - and
consistency leads to more comprehensible code.

The funtional notation is far more restrictive than the C style casts.
It cannot be used to convert pointers - which are far and away the most
dangerous conversions to undertake. Certainly for doubles, ints, chars
and the rest of the built in types, using the static_cast notation
would be slightly ridiculous. There is no polymorphism with the
built-in types so whatever the statically declared type of a variable
happens to be, will be its type for all intents and purposes. In light
of that fact, one might as well use the notation that creates the least
clutter in the source code, and that looks the most like existing code
that performs the identical operation for class types.

Greg
 
A

Alf P. Steinbach

* Greg:
The expression double(n) is uniquely C++ both syntactically and
conceptually since it "constructs" the double value by converting n:

Do you by any chance have pointy hair?

It cannot be used to convert pointers - which are far and away the most
dangerous conversions to undertake.

int main()
{
typedef unsigned char* UcPtr;

UcPtr p;
double c;

p = UcPtr( &c );
}
 
B

benben

But this is EXACTLY why C++ cast operators look this way: they are so
So did they really invent this ugly syntax so I
shouldn't use casting, or is this just an urban
myth?

That's what Bjarne Stroustrup said in his faq, have a read.
I'd guess there are people from academia telling you
not to cast ever, but no industry scale C++ system
can do without it. And how can I find the fraction of
int 10 to int 35 without casting?

Not to cast ever is unrealistic, indeed. However, knowing the potential
danger of cast yet leaving casts all over the source is asking for trouble,
especially during debugging. A better way would be writing a function which
does the cast for its callers. This way the code becomes more explicit and,
most importantly, you are localizing some dangereous operations and that'd
make debugging and maintaining much easier. Now, you would have ended up
with a bunch of such functions that really are doing the same thing with
different types; to generalize, and to make code concise, you can use
template. Now you end up with some function templates that look like the
following:

template <typename TypeTo, typename TypeFrom>
TypeTo my_safe_cast(const TypeFrom& from)
{
// localized dangereous casting code...
}

apple a = my_safe_cast<orange>(o);

Which, basically, is what static_cast, dynamic_cast, and reinterpret_cast
are.
And why do I need a syntax so that _Notepad_ can tell
me where my casts are? First, I wouldn't categorize
code by casts (I don't need a way to find them all),
and a _proper_ editor would tell me (if asked) anyway.

I haven't seen an editor that can effectively tell me where all the C-style
casts are. This is not for catagorizing code but for maintainance. Again, if
my program is plagued by overflow/underflow and bit and byte level runtime
errors I'd be glad to be able to find out all casting, bit operation,
limits, etc in a couple of seconds.
Isn't it so that static_cast (and its cousins) is an
aid for the compiler to to proper type checking and
that neither the compiler nor the runtime environment
can help me when trying to find the fraction of two
integers?

Type casting by itself doesn't have much meaning. You might want to cast a
double to an int this way and I might want it the other way. Some casting
operations are quite trivial while others can be quite complex and
expensive. So there are always different ways to cast from one type to
another and that's why C++:

1. provides different cast operators that does a specific job
2. provides its cast operators as if they are function templates so that
you can write your own cast operators.

Having that said, type cast is not the best way for type conversion.
Whenever possible, it is easier, simpler, and more managable to start with
copy constructor, assignment overloading, and explicit functions.

No worries!

Ben
 
G

Greg

Alf said:
* Greg:

Do you by any chance have pointy hair?



int main()
{
typedef unsigned char* UcPtr;

UcPtr p;
double c;

p = UcPtr( &c );
}

Granted, it's possible to circumvent the restrictive syntax of this
method of conversion, but if someone is determined to convert a char
pointer to a double, I doubt that they would go about it this way.

The function notation for explicit conversions was added to C++ for a
reason. It does not exist for backward compatibility with C. There must
therefore be situations where its use would be a better choice than any
other conversion operator. And if converting an int to a double is not
one of those cases, then for what kind of conversion was it meant to be
used?

Greg
 
O

Old Wolf

Only one of the operands of '/' (or any other arithmetic
operator) needs to be converted:

double fraction = double(n) / total;

Another option would be:
double fraction = n;
fraction /= total;
I like this. I did search for backing on this syntax
originally but neither S. Meyers nor A. Sutter mentions
it. And my colleges didn't knew about it.

Could you please back it with some links?

It's called "constructing a temporary object".
Here is an analogous example, with string
instead of double:

string name = string("john") + " doe";

I fail to see how this is un-C++ as another poster
claimed; would he prefer to write:
string name = static_cast<string>("john") + " doe";
?

One reason that constructor syntax can be applied to
intrinsic types as well as class types is this:

template<typename A, typename B>
A sum(B x, B y)
{
return A(x) + y;
}

// in a function somewhere
cout << sum<double>(1, -5) << '\n';
cout << sum<string>("john", " doe") << '\n';
 
A

Alf P. Steinbach

* Greg:
Granted, it's possible to circumvent the restrictive syntax of this
method of conversion,

The syntax is not restrictive, quite the opposite, and no circumvention is
needed.

but if someone is determined to convert a char
pointer to a double, I doubt that they would go about it this way.

Do you at all understand that your statement "it cannot be used to convert
pointers" is incorrect?

The function notation for explicit conversions was added to C++ for a
reason. It does not exist for backward compatibility with C. There must
therefore be situations where its use would be a better choice than any
other conversion operator. And if converting an int to a double is not
one of those cases, then for what kind of conversion was it meant to be
used?

Do you by any chance have pointy hair?
 
A

Alf P. Steinbach

* Old Wolf:
It's called "constructing a temporary object".

No, in general it's not, because it's equivalent to a C-style cast: the
standard uses the word equivalent.

Here is an analogous example, with string
instead of double:

string name = string("john") + " doe";

I fail to see how this is un-C++ as another poster
claimed; would he prefer to write:
string name = static_cast<string>("john") + " doe";
?

The example is not analogous except partially in syntax.

<url: http://www.nizkor.org/features/fallacies/straw-man.html>.

When you attack someone's position, be accurate, be truthful, name names,
and so on.
 
J

Jacob

Old said:
double fraction = n;
fraction /= total;

This is certainly a way to compute the fraction n/total
without using casts, but it is conceptually wrong;
At the instance between the two statements "fraction"
will be incorrect and represents a pending bug.
 
O

Old Wolf

Jacob said:
This is certainly a way to compute the fraction n/total
without using casts, but it is conceptually wrong;
At the instance between the two statements "fraction"
will be incorrect and represents a pending bug.

Huh?

Are you saying this is bad because someone might
remove the second statement at a later date?
 
O

Old Wolf

Alf said:
* Old Wolf:
[re. the construction: double(n) ]
No, in general it's not, because it's equivalent to a C-style cast: the
standard uses the word equivalent.

Well, constructing a [X] with [Y] as parameter, is equvalent
to casting [Y] to [X], is it not? Certainly no conforming
program can tell the difference. You conveniently snipped
the template example, which I think is a good illustration
of temporary objects.

Here's another example:

double get() { return double(); }

The return statement creates a temporary double and then
returns it. No arguments here.

But you would say that the following does not create a
temporary double? :

double get() { return double(1); }
 

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,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top