gratuitous static_cast in assignment

T

The Unlord

Hi,

I'm currently using a lot of other people's code, and I kept stumbling
upon what looked to me as a 'weird habit':

In some general include dir there's a file with a bunch of typedefs like

typedef unsigned char UINT8; //!< 8 bits of unsigned integer

nothing wrong with that, I guess, but on every occasion where a type
like that is assigned, you see things like this:

UINT8 Dummy = static_cast<UINT8>(0);

I personally completely fail to see the logic in that...
I thought compilers ought to be smart enough to figure that one out!

Even in if tests the conversion is done:

void f(UINT8 value)
{
if (value == static_cast<UINT8>(2))
{
// do something
}
}

Could there be any logic behind this, because to me it looks like trying
to be smarter than the compiler, and perhaps even dangerous:
if you write this:
UINT8 Dummy = static_cast<UINT8>(-2);
the compiler will never complain, as it thinks you know better. But
maybe it's a typo, and this:
UINT8 Dummy = -2;
might at least give you a warning...

Can somebody enlighten me?
Thanks!
 
M

Michael DOUBEZ

The said:
I'm currently using a lot of other people's code, and I kept stumbling
upon what looked to me as a 'weird habit':

In some general include dir there's a file with a bunch of typedefs like

typedef unsigned char UINT8; //!< 8 bits of unsigned integer

nothing wrong with that, I guess, but on every occasion where a type
like that is assigned, you see things like this:

UINT8 Dummy = static_cast<UINT8>(0);

I personally completely fail to see the logic in that...
I thought compilers ought to be smart enough to figure that one out!

You are right.
Even in if tests the conversion is done:

void f(UINT8 value)
{
if (value == static_cast<UINT8>(2))
{
// do something
}
}

Could there be any logic behind this, because to me it looks like trying
to be smarter than the compiler, and perhaps even dangerous:
if you write this:
UINT8 Dummy = static_cast<UINT8>(-2);
the compiler will never complain, as it thinks you know better. But
maybe it's a typo, and this:
UINT8 Dummy = -2;
might at least give you a warning...

Can somebody enlighten me?

Perhaps the coder was paid by the character or he was following a stupid
guideline requiring that the type be specified for all constant (in
this case Dummy=UINT8(2) is less verbose).
 
B

Bill Davy

Michael DOUBEZ said:
You are right.


Perhaps the coder was paid by the character or he was following a stupid
guideline requiring that the type be specified for all constant (in this
case Dummy=UINT8(2) is less verbose).

Or may be the programmer is placating Lint? But Lint is a useful tool. And
sometimes the lhv does not have its type immediately obvious:

m_Dummy = -2;

When you have to maintain software (a much more difficult task than mere
coding), that line is a worry and therefore needs to be clarifed. Did the
original programmer slip up or did they know what they are doing? They can
tell the maintainer by using an explicit cast. It can be overdone, of
course. But if static_cast is used uniformly, its absence can indicate the
orginal progarmmer overlooked something.

Bill
 
M

Michael DOUBEZ

Bill said:
Or may be the programmer is placating Lint? But Lint is a useful tool. And
sometimes the lhv does not have its type immediately obvious:

m_Dummy = -2;

In which case, you can specify the type:

m_Dummy = uint8_t(-2);

When you have to maintain software (a much more difficult task than mere
coding), that line is a worry and therefore needs to be clarifed.

static_cast is so verbose that I doubt it.
Did the
original programmer slip up or did they know what they are doing? They can
tell the maintainer by using an explicit cast. It can be overdone, of
course. But if static_cast is used uniformly, its absence can indicate the
orginal progarmmer overlooked something.

The best being perhaps to name the constants (except for indices and
trivial values).
 
T

The Unlord

When you have to maintain software (a much more difficult task than mere
coding), that line is a worry and therefore needs to be clarifed. Did the
original programmer slip up or did they know what they are doing? They can
tell the maintainer by using an explicit cast. It can be overdone, of
course. But if static_cast is used uniformly, its absence can indicate the
orginal progarmmer overlooked something.

Bill

I think by using it everywhere, it loses it's function. It's like
turning off all compiler warnings.

If you write
UINT8 Dummy = statuc_cast<UINT8>(-1);
you want to indicate to the compiler 'Yeah, I know it's an unsigned, but
I want an all 1's bitmask, so don't complain.'
The compiler would warn you about it, but you know what you're doing, so
you don't want the warning.
That's the only good reason for using the static_cast it, imho

Writing
UINT8 Dummy = statuc_cast<UINT8>(0);
is pure nonsense.
 
B

Bill Davy

The Unlord said:
I think by using it everywhere, it loses it's function. It's like turning
off all compiler warnings.

If you write
UINT8 Dummy = statuc_cast<UINT8>(-1);
you want to indicate to the compiler 'Yeah, I know it's an unsigned, but I
want an all 1's bitmask, so don't complain.'
The compiler would warn you about it, but you know what you're doing, so
you don't want the warning.
That's the only good reason for using the static_cast it, imho

Writing
UINT8 Dummy = statuc_cast<UINT8>(0);
is pure nonsense.

~0 is more like "all ones" than -1, imho. -1 is arithmetic, ~0 is logic.

I would certainly like to see a comment.

Hopefully, as suggested by MB, a named constant would make everything
clearer and would be of the correct type.

Bill
 
J

James Kanze

~0 is more like "all ones" than -1, imho. -1 is arithmetic,
~0 is logic.

Sort of. What is probably wanted is
-static_cast< targetType >( 1 )
(where targetType is an unsigned integral type). Or
~static_cast< targetType >( 0 ).

Depending on the types involved, ~0 may give a wrong result (at
least on machines which aren't 2's complement)---for better or
for worse, - is well defined on unsigned types.
 
B

Balog Pal

The Unlord said:
void f(UINT8 value)
{
if (value == static_cast<UINT8>(2))
{
// do something
}
}

Could there be any logic behind this, because to me it looks like trying
to be smarter than the compiler, and perhaps even dangerous:
if you write this:
UINT8 Dummy = static_cast<UINT8>(-2);

If you put this kind in the == example above, it will make a difference.

UINT8 value = -2; // unsigned char
if (value == static_cast<UINT8>(-2)) // 254 == 254 true
if (value == -2) // 254 == -2 false

promotions will go to int in both lines, resulting the stuff in comment.
the compiler will never complain, as it thinks you know better. But maybe
it's a typo, and this:
UINT8 Dummy = -2;
might at least give you a warning...

In assignments I would not bother with casts for sure -- especially not
sprinkled in code, but introduce constants somewhere.
In comarision you better be aware of signed-unsigned mismatch, and use u
postfix or cast.
Some compilers warn about it, it's wise to promote to error. I recall not
one bug from unwanted/unexpected promotion. Especially in cases meant to
deal with raw bytes that happened to be in a buffer 'char[]' instead of
unsigned char -- and eventually failed to match the >=128 values...

Too bad we don't have postfixes for char and short types...
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top