When are unnecessary casts useful?

C

Clark S. Cox III

matevzb said:
This isn't C, it's a C++ constructor if I'm not mistaken. It has a
different meaning than a cast, it is however nevertheless ugly.

<OT>
No, it is a cast, albeit with a different syntax. In C++, the following
are semantically identical:

char(b+c*c-d)
(char)(b+c*c-d)
Almost as ugly as the abuse ("overloading") of the shift operator.
If I had a penny for each bug I found due to someone "saving some
keystrokes"...

<OT>
Though it does "save some keystrokes" (which, I agree is a horrible
justification for allowing something), that is not the reason for
allowing that syntax.
</OT>
 
D

David T. Ashley

ais523 said:
%cat -n test.c
1 int main(void)
2 {
3 char c='c';
4 char* a;
5 a=&c;
6 if(!a || *a > 10) c++;
7 if((!a) || (*a > 10)) c++;
8 if(*a = 10) c++;
9 if((*a = 10)) c++;
10 return 0;
11 }
%gcc -W -Wall test.c
test.c: In function `main':
test.c:8: warning: suggest parentheses around assignment used as truth
value

Note that my version of gcc hasn't warned on line 9; it takes the extra
parentheses as an instruction to suppress the warning. So excess
parenthesisation of this sort can have an effect on compiler
diagnostics, even if it doesn't affect the behaviour of the code.

The behavior you illustrated is unexpected. What a surprise!

We all know that one of the most frequent human errors (at least, until
you've used 'C' for a long time) is to write something like:

if (x=0)

when you really mean

if (x==0)

so I'm not surprised that the compiler will flag that.

But that the extra parens suppress it really surprises me.

Maybe the rationale was if you parenthesize it you are saying "Yo, compiler,
I do understand that this assignment has a value, and I want the value of
it".

Or (although I doubt it), it could be bug in the compiler.

I've never seen this. Thanks.
 
P

Peter Nilsson

Yevgen said:
GCC and Intel compiler have this thing too, it's not like some
evil microsoft invention picked up by Jacob Navia. You don't want
it you don't use it.

But unlike gcc, from what Jacob has said, he isn't giving me the option
of disabling the warning.

I don't mind warnings. What I mind is compiler writers telling me and
other programers, via pester power, what is and what isn't good
practice.
Down conversions are useful and not at all uncommon in C, viz...

char *s = buffer;
int ch = getchar();
*s++ = ch;

If lcc-win32 gives a warning everytime for such code, whether I want it
too or not, chances are I would stop using lcc-win32 quite quickly.
 
J

jacob navia

Peter Nilsson a écrit :
But unlike gcc, from what Jacob has said, he isn't giving me the option
of disabling the warning.

I don't mind warnings. What I mind is compiler writers telling me and
other programers, via pester power, what is and what isn't good
practice.
Down conversions are useful and not at all uncommon in C, viz...

char *s = buffer;
int ch = getchar();
*s++ = ch;

If lcc-win32 gives a warning everytime for such code, whether I want it
too or not, chances are I would stop using lcc-win32 quite quickly.

This warning is enabled when you increase the warning level from the
default one, or when you invoke the compiler in "check" mode.
 
K

Keith Thompson

Steffen Buehler said:
Interesting or not, I prefer the latter expression, too. Functions look
more elegant to me than ugly cast operators.
[...]

If cast operators are ugly, that's a feature, not a bug. Discouraging
the use of unnecessary casts (as most of them are) is a good thing.
(I don't find the syntax ugly, but YMMV.)
 
C

CBFalconer

David T. Ashley said:
The behavior you illustrated is unexpected. What a surprise!

We all know that one of the most frequent human errors (at least,
until you've used 'C' for a long time) is to write something like:

if (x=0)

when you really mean

if (x==0)

so I'm not surprised that the compiler will flag that.

But that the extra parens suppress it really surprises me.

Maybe the rationale was if you parenthesize it you are saying "Yo,
compiler, I do understand that this assignment has a value, and I
want the value of it".

Or (although I doubt it), it could be bug in the compiler.

No bug. in "if (x = 0) {" the tested item is an assignment
statement, which incidentally also yields a value. In "if ((x =
0)) {" the tested statement is a parenthized expression, which
intrincically has a value, and the compiler can tell what is going
on. Of course the sane thing to do is to write those as "if (0 =
x)", assuming you want to test against 0 and avoid failing to flag
the erroneous assignment statement.
 
S

Simon Biber

David said:
ais523 said:
%cat -n test.c
1 int main(void)
2 {
3 char c='c';
4 char* a;
5 a=&c;
6 if(!a || *a > 10) c++;
7 if((!a) || (*a > 10)) c++;
8 if(*a = 10) c++;
9 if((*a = 10)) c++;
10 return 0;
11 }
%gcc -W -Wall test.c
test.c: In function `main':
test.c:8: warning: suggest parentheses around assignment used as truth
value

Note that my version of gcc hasn't warned on line 9; it takes the extra
parentheses as an instruction to suppress the warning. So excess
parenthesisation of this sort can have an effect on compiler
diagnostics, even if it doesn't affect the behaviour of the code.
[..]

But that the extra parens suppress it really surprises me.

The text of the diagnostic message clearly suggests adding brackets to
assignments used as truth values. There must be a reason for doing so --
perhaps as mundane as simply to suppress the warning.
Maybe the rationale was if you parenthesize it you are saying "Yo, compiler,
I do understand that this assignment has a value, and I want the value of
it".

Yes, exactly.
Or (although I doubt it), it could be bug in the compiler.

No. It's by design.

Unfortunately not all compilers take the hint when you just add brackets
-- some will continue to warn you. So I've taken to adding both brackets
and != 0 to the end:

if((x = y) != 0)

This is pretty warning-proof.
 
K

Keith Thompson

CBFalconer said:
No bug. in "if (x = 0) {" the tested item is an assignment
statement, which incidentally also yields a value. In "if ((x =
0)) {" the tested statement is a parenthized expression, which
intrincically has a value, and the compiler can tell what is going
on.

The expression is effectively identical with or without the
parentheses. Strictly speaking, the form without the parentheses is
not an "assignment statement"; it's not a statement at all, and an
assignment is an expression, not a statement. (Like any expression,
you can make it an expression by adding a semicolon.) Both forms have
exactly the same result, side effects, and any other semantics you can
think of.

The compiler's decision to issue a warning only for the
unparenthesized form is reasonable, since that form is far more likely
to be the result of mistyping "==" as "=", but as far as the language
is concerned it's essentially arbitrary.
Of course the sane thing to do is to write those as "if (0 =
x)", assuming you want to test against 0 and avoid failing to flag
the erroneous assignment statement.

(I've expressed my opinion on this kind of thing before; I won't bore
everyone by doing so again here.)
 
D

David T. Ashley

This is pretty warning-proof.

This is my first time seeing the term "warning-proof". It suggests a
programmer who has been harrassed by compilers throughout a long career. It
has the flavor of a woman saying "stalker-proof".
 
M

Malcolm McLean

Ian Collins said:
Does that include 64 bit char?
Ideally the char / byte link would be broken, and a byte would become an
octet, with compiler gyrations for the few platforms where that is a
problem. chars would then be characters, and integer operations on them
could be deprecated and later disallowed.

However it is unlikely to happen. 64 bit ints are achieveable without
changing the standard.

How many bits you need for a char depends on your language. 64 is a good
choice, however, because then the bits can be a 8x8 raster.
 
C

Chris Dollin

Malcolm said:
Ideally the char / byte link would be broken, and a byte would become an
octet, with compiler gyrations for the few platforms where that is a
problem. chars would then be characters, and integer operations on them
could be deprecated and later disallowed.

However it is unlikely to happen. 64 bit ints are achieveable without
changing the standard.

How many bits you need for a char depends on your language. 64 is a good
choice, however, because then the bits can be a 8x8 raster.

Well, (a) we are no longer in the glory days of the BBC Model B, where
an 8x8 programable character definition was really rather whizzy, and
(b) some moderately well-known character sets wouldn't fit that
definition and (c) it confuses the character with a particular
bitmapped presentation.
 
S

Simon Biber

David said:
This is my first time seeing the term "warning-proof". It suggests a
programmer who has been harrassed by compilers throughout a long career. It
has the flavor of a woman saying "stalker-proof".

Not a terribly long career in C. I have been programming for 19 years
but only 6 years in C. I like all my code to compile cleanly, and that
means with no warnings. Preferably on the highest sane [1] warning level.

[1] I reserve the right to define 'sane' however I like. For example,
currently it's simply -Wall -W -O2 on gcc.
 
M

Mark McIntyre

Not a terribly long career in C. I have been programming for 19 years
but only 6 years in C. I like all my code to compile cleanly, and that
means with no warnings.

I sympathise with this. Its frequently extremely difficult if you use
and of the MS compiler headers mind you...
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
R

Richard Heathfield

Mark McIntyre said:
I sympathise with this. Its frequently extremely difficult if you use
and of the MS compiler headers mind you...

In VS6, the only standard header I know of that provokes a diagnostic
message, even at the highest level, is math.h (because it contains a BCPL
comment). Are you saying VS has got worse since then?
 
M

matevzb

Mark McIntyre said:


In VS6, the only standard header I know of that provokes a diagnostic
message, even at the highest level, is math.h (because it contains a BCPL
comment). Are you saying VS has got worse since then?
Yes, very much so. The following code
#include <stdio.h>

int
main (void)
{
int i = 10;
char str[256];

sprintf (str, "%d", i);
return 0;
}
produces a warning in VC 2005 (express).
c:\tmp\a.c(8) : warning C4996: 'sprintf' was declared deprecated
c:\program files\microsoft visual studio
8\vc\include\stdio.h(345) : see declaration of 'sprintf'
Message: 'This function or variable may be unsafe. Consider using
sprintf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'
In my experience VC got quite worse in other areas as well.
 
R

Richard Heathfield

matevzb said:
Are you saying VS has got worse since then?

Yes, very much so. The following code
#include <stdio.h>

int
main (void)
{
int i = 10;
char str[256];

sprintf (str, "%d", i);
return 0;
}
produces a warning in VC 2005 (express).
c:\tmp\a.c(8) : warning C4996: 'sprintf' was declared deprecated

Oh dear.

Well, it's legal. They can say "warning: send Bill more money" if they like,
and it would still be conforming. But a plethora of spurious warnings is
not going to win Visual Studio any customers, and may well be sufficient to
drive old customers into the arms of other suppliers.
 
R

Randy Howard

matevzb said:
Are you saying VS has got worse since then?

Yes, very much so. The following code
#include <stdio.h>

int
main (void)
{
int i = 10;
char str[256];

sprintf (str, "%d", i);
return 0;
}
produces a warning in VC 2005 (express).
c:\tmp\a.c(8) : warning C4996: 'sprintf' was declared deprecated

Oh dear.

Well, it's legal. They can say "warning: send Bill more money" if they like,
and it would still be conforming. But a plethora of spurious warnings is
not going to win Visual Studio any customers, and may well be sufficient to
drive old customers into the arms of other suppliers.

That's what happened here. Good riddance to bad rubbish.
 
M

Mark McIntyre

Mark McIntyre said:


In VS6, the only standard header I know of that provokes a diagnostic
message, even at the highest level, is math.h (because it contains a BCPL
comment). Are you saying VS has got worse since then?

I'm not actually sure its *possible* for some compilers to get /worse/
at producing annoying messages when on sensible warninglevels...

(FWIW its massively worse when you're using any of the Win32 headers,
these are packed with L3 and L4 warnings)

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
C

CBFalconer

Mark said:
.... snip ...


I'm not actually sure its *possible* for some compilers to get /worse/
at producing annoying messages when on sensible warninglevels...

(FWIW its massively worse when you're using any of the Win32 headers,
these are packed with L3 and L4 warnings)

A vendor doesn't have to make his headers pass the warning levels,
because they are specific to the implementation. However he should
have the intelligence to suppress warnings from those constructs in
those headers. MS doesn't.
 
G

Giorgos Keramidas

Ian Collins said:
Does that include 64 bit char?

[...]
How many bits you need for a char depends on your language. 64 is a good
choice, however, because then the bits can be a 8x8 raster.

<OT>
Or a utf-16 glyph index *and* lots of space for metadata, which smart
editors would use to keep other sorts of information.
</OT>

But this is quickly getting way off-topic :)
 

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

Similar Threads


Members online

Forum statistics

Threads
473,796
Messages
2,569,645
Members
45,366
Latest member
GayT017679

Latest Threads

Top