Strange - a simple assignment statement shows error in VC++ but worksin gcc !

D

Default User

CBFalconer said:
Default User wrote:

He removed the advocacy group. Any reader there never saw his
reply. With the follow-up, that reader would see the reply. Apart
from that, assuming accurate readers, the effects are the same.

They will see the reply but not the original. What is the sense in
that? In my opinion, follow-up-to has one use only. When a thread needs
to be "moved" to another group, the reply should be cross-posted to the
new group and the original, and a follow-up set so that further
discussion is on the new group only.




Brian
 
R

Rainer Weikusat

Joe Pfeiffer said:
It makes it clear that the programmer knew a conversion had to take
place.

Not any more than just writing the code which would cause it. What is
so special about the assignment-operator that the assumption that what
was written likely wasn't intended would be justified? And is there
some sort of rule for this which would explain why the same shouldn't
be assumed about the use of any other operator, IOW, is it possible to
mechanically decide if a certain operator has this quality, other by
gathering statistics about programming errors in some body of existing
code, given the assumptions that these will be generally
representative and not mainly contain information about the particular
group of people who wrote it?
Any inferences regarding the competence of the programmer depend on
context.

'competence' is somewhat more general than 'knowledge of the
particulars of something', meaning, I would expect that 'a competent
programmer' would be aware of the properties of fixed-width binary
representations of integral numbers, but not necessarily know about
the easiest way to express a particular operation in a language he
might not be very familiar with. But while people who write code with
the explicit intent to make it look confusing exist, I believe that
most of the de facto decorative parts of source code exist because
someone was honestly convinced that they were actually necessary or at
least unsure about this and rather desiring to play it safe.
 
D

David Schwartz

Reasonably recent GCC should issue a warning "Comparison is always true
due to limited type range" or something like that on the second loop.

I believe GCC 4.3.3 will only issue a warning with a non-standard
warning flag. This bug was caught in code that compiles without
warnings with -Wall on GCC 4.3.3.

I think it was -Wextra, but it might have been -Wconversion. If you
don't code along the rules I'm suggesting in this thread, those
warning flags will produce thousands of warnings in a significant
codebase. So you're not too likely to notice that one buried in the
mix.

You might think very little legitimate code would produce that
warning. But it's not true, quite a bit of legitimate code (mostly
macro tricks, though, like eating a semicolon) does if you don't adopt
special techniques to avoid it.

DS
 
C

CBFalconer

David said:
.... snip ...


I agree. Here, the types are so close together that it would be
absurd to assume the programmer didn't intend the conversions.
However, an automated testing tool couldn't tell. You may or
may not care about that.

There is no problem here. All those types are unsigned, and thus
do modulo arithmetic. They can never overflow. However the value
may change when moved fom uint8_t to uint32_t.
 
C

CBFalconer

.... you snipped the problem and the suggested fix ...
They will see the reply but not the original. What is the sense
in that? In my opinion, follow-up-to has one use only. When a
thread needs to be "moved" to another group, the reply should be
cross-posted to the new group and the original, and a follow-up
set so that further discussion is on the new group only.

Not so. The distribution is not altered until THEY reply.
 
D

David Schwartz

There is no problem here.  All those types are unsigned, and thus
do modulo arithmetic.  They can never overflow.  However the value
may change when moved fom uint8_t to uint32_t.

I thought all integer over/underflow was undefined. I could be
remembering incorrectly.

DS
 
K

Keith Thompson

David Schwartz said:
I thought all integer over/underflow was undefined. I could be
remembering incorrectly.

You are. For signed integer types and for floating-point types, an
arithmetic operation that yields a result outside the range of the
type results in undefined behavior. For unsigned integer types, it
wraps around modulo MAX+1, where MAX is the largest value of the type.

The rules are a bit different for conversions; when the target type is
signed, an overflow either yields an implementation-defined result or
raises an implementation-defined signal.
 
D

David Schwartz

You are. For signed integer types and for floating-point types, an
arithmetic operation that yields a result outside the range of the
type results in undefined behavior. For unsigned integer types, it
wraps around modulo MAX+1, where MAX is the largest value of the type.

You are correct. Thanks for the info.

DS
 
R

Rainer Weikusat

Keith Thompson said:
You are. For signed integer types and for floating-point types, an
arithmetic operation that yields a result outside the range of the
type results in undefined behavior. For unsigned integer types, it
wraps around modulo MAX+1, where MAX is the largest value of the type.

The rules are a bit different for conversions; when the target type is
signed, an overflow either yields an implementation-defined result or
raises an implementation-defined signal.

It should be noted that this inconsistency was invented by 'some
gcc-people' in order to enable them to interpret the statement 'an
exceptional condition occured' as 'something happened which I want to
consider as exceptional' instead of the usual meaning of 'hardware
signalled an error condition'. And it is even more inconsistent as it
seems, because the type of an object a value is supposed to be stored
into has to be taken into consideration in order to determine which
operations performed by some code qualify as 'I am going to ignore
this, since this will break existing code and confuse the shit out of
most people', eg type-wise, there is no difference between the left
side of

unsigned u;

u = INT_MAX + 1;

and

int i;

i = INT_MAX + 1;

In both cases, two values with a (conceptual) type of 'int' are added,
producing a value outside the range of values of int. For the second
case, the operation itself is deemed as having 'undefined behaviour'
in order to get around the conversion requirement and consequently,
the same must be true for the first case, causing the conversion
requirements for unsigned to become 'dead code' whenever someone
should want that, too. This amusing 'innovation' should really apply
to all arithmetic operations where no operands which are already
beyond the 'legal' range of int-values appear.
 
R

Rainer Weikusat

Keith Thompson said:
You are. For signed integer types and for floating-point types, an
arithmetic operation that yields a result outside the range of the
type results in undefined behavior. For unsigned integer types, it
wraps around modulo MAX+1, where MAX is the largest value of the type.

The rules are a bit different for conversions; when the target type is
signed, an overflow either yields an implementation-defined result or
raises an implementation-defined signal.

It should be noted that this inconsistency was invented by 'some
gcc-people' in order to enable them to interpret the statement 'an
exceptional condition occured' as 'something happened which I want to
consider as exceptional' instead of the usual meaning of 'hardware
signalled an error condition'. And it is even more inconsistent as it
seems, because the type of an object a value is supposed to be stored
into has to be taken into consideration in order to determine which
operations performed by some code qualify as 'I am going to ignore
this, since this will break existing code and confuse the shit out of
most people', eg type-wise, there is no difference between the right
side of

unsigned u;

u = INT_MAX + 1;

and

int i;

i = INT_MAX + 1;

In both cases, two values with a (conceptual) type of 'int' are added,
producing a value outside the range of values of int. For the second
case, the operation itself is deemed as having 'undefined behaviour'
in order to get around the conversion requirement and consequently,
the same must be true for the first case, causing the conversion
requirements for unsigned to become 'dead code' whenever someone
should want that, too. This amusing 'innovation' should really apply
to all arithmetic operations where no operands which are already
beyond the 'legal' range of int-values appear.
 
D

Default User

CBFalconer said:
Default User wrote:

Not so. The distribution is not altered until THEY reply.

I don't think you understand the point. I am also not inclined to
attempt to explain it to you. In general, there's been a lot of that
going on to poor effect lately.




Brian
 
G

Guest

It would be obvious to anyone who reviews C code professionally

I review code professionally and it *isn't* obvious to me.
that
the cast was put there to indicate to someone looking at the code that
the conversion was intended and the person who put the cast in there
is vouching for its safety.

It says to me that the person who wrote the code wasn't sure
about the automatic conversion so bunged a cast in. Just In Case.

I see a lot of unnecessary casts


It says, "I know the range of the type on
the right exceeds the range of the type on the left, and I have made
sure that the value cannot actually be out of range."

<snip>
 
P

Peter Köhlmann

I review code professionally and it *isn't* obvious to me.


It says to me that the person who wrote the code wasn't sure
about the automatic conversion so bunged a cast in. Just In Case.

It also makes for readability of the source. It serves to highlight that
the programmer really *intended* that cast
I see a lot of unnecessary casts

Lots are *not* unnecessary.
If you change architecture or OS platform, assumptions tend to change.
Just look at the differences of "int"
 
I

Ian Collins

Peter said:
It also makes for readability of the source. It serves to highlight that
the programmer really *intended* that cast

No, it just makes the reader do a double take and wonder why the
unnecessary cast is there.
Lots are *not* unnecessary.
If you change architecture or OS platform, assumptions tend to change.
Just look at the differences of "int"

One good reason not to cast: it will suppress useful compiler warnings.
 
D

David Schwartz

I review code professionally and it *isn't* obvious to me.

To be clear, you are claiming that:

1) You saw a cast, and

2) It was not obvious from this that the programmer knew that there
would be a conversion and intended it.

That is what you are claiming? If so, what did you conclude when you
saw the cast? That perhaps the programmer had no idea the cast caused
a conversion? Or perhaps the programmer put the cast in even though he
didn't intend the conversion?
It says to me that the person who wrote the code wasn't sure
about the automatic conversion so bunged a cast in. Just In Case.

So you did not conclude that the conversion was intended? You still
thought perhaps the conversion was accidental?

And you didn't conclude that the programmer vouched for the safety of
the cast? So you thought that maybe the programmer thought the
conversion was unsafe but still specifically requested it?

Sorry, I don't believe you.
I see a lot of unnecessary casts

Sure, but you still know when you see the cast that:

1) The programmer is vouching for the safety of the cast, and

2) The programmer intended the conversion.

You, arguably, may have no idea why he opted to put the cast there
rather than omit it. Nevertheless, you still conclude those two things
-- two things you could not conclude if the cast wasn't there.

Hmm, there are two *true* things you conclude when the cast is there
that you can't conclude if the cast is not there. Maybe *that's* why
the programmer put the cast there? Nope, I guess your reasoning stops
one step short of that, fair enough. But I never claimed you would
reach that conclusion.

DS
 
M

Måns Rullgård

David Schwartz said:
To be clear, you are claiming that:

1) You saw a cast, and

2) It was not obvious from this that the programmer knew that there
would be a conversion and intended it.

I would make that claim.
That is what you are claiming? If so, what did you conclude when you
saw the cast? That perhaps the programmer had no idea the cast caused
a conversion? Or perhaps the programmer put the cast in even though he
didn't intend the conversion?

When I see a cast like that, I assume a so-called programmer got a
warning message along the lines of "warning: bla bla conversion
without a cast", and promptly stuck a cast there without giving it a
second thought. I see that happening all the time.
 
K

Keith Thompson

David Schwartz said:
On Apr 6, 2:33 am, (e-mail address removed) wrote: [...]
I see a lot of unnecessary casts

Sure, but you still know when you see the cast that:

1) The programmer is vouching for the safety of the cast, and

2) The programmer intended the conversion.
[...]

Certainly (well, almost certainly) the presence of a cast implies that
the programmer intended a conversion. But it does *not* imply, any
more than the absence of a cast, that the programmer is vouching for
the safety of the conversion. Nothing short of a comment saying "I
vouch for the safety of this conversion" would convey that information
to me.

Since some compilers, in the case being discussed, will issue a
warning if there is no cast, but will not issue a warning if there is
a cast, it's entirely possible that the programmer added the cast
merely to silence the warning. This does not imply that the
programmer knew what he was doing.

Another possibility is that the programmer used a cast because he
wasn't aware that the conversion would be done implicitly without it.

If I'm going to assume perfect competence on the part of the
programmer, then an assignment without the cast tells me just as much
as the assignment with the cast, since the programmer must be aware
that there's an implicit conversion, and wouldn't have written the
assignment without knowing that it's safe. Without that assumption,
the presence of an *unnecessary* cast would, in my mind, cast (*sigh*)
doubt on the programmer's competence.

If you work in an environment where a cast always means "I guarantee
the safety of this conversion", then the assumptions you make are
reasonable in that environment. But that's not what a cast means,
either in the language as defined by the C standard or in any
programming environment I've seen.

Don't assume that your experience is universal.
 
J

jameskuyper

David said:
To be clear, you are claiming that:

1) You saw a cast, and

2) It was not obvious from this that the programmer knew that there
would be a conversion and intended it.

That is what you are claiming? If so, what did you conclude when you
saw the cast? That perhaps the programmer had no idea the cast caused
a conversion? Or perhaps the programmer put the cast in even though he
didn't intend the conversion? ....

So you did not conclude that the conversion was intended? You still
thought perhaps the conversion was accidental?

I've seen people insert casts just to shut up a compiler. It was very
clear, upon questioning them, that they had little or no idea what the
cast did, they were just following a suggestion contained in the
compiler's messages. If the conversion had consequences that they did
not understand would occur (such as wrapping on overflow or truncation
of the fractional portion of a floating point value), does such a
conversion count as intentional?
And you didn't conclude that the programmer vouched for the safety of
the cast? So you thought that maybe the programmer thought the
conversion was unsafe but still specifically requested it?

In the cases I'm thinking of, the programmers had no idea whether the
casts was safer or not, they were just trying to shut up a compiler
warning. They may have thought that the compiler knew best, but they
were most certainly not vouching personally to the safety of the code.
Their argument was "the compiler told me to do this, so it must be
safe". In other words, they were rejecting personal responsibility,
and were holding the compiler (and by implication, the compiler's
vendor) responsible for generating a diagnostic that implied that the
cast was a good idea.. In a couple of those cases, the cast was
definitely NOT safe, for reasons the programmer did not understand.
 
H

Harald van Dijk

In the cases I'm thinking of, the programmers had no idea whether the
casts was safer or not, they were just trying to shut up a compiler
warning. They may have thought that the compiler knew best, but they
were most certainly not vouching personally to the safety of the code.
Their argument was "the compiler told me to do this, so it must be
safe".

That reminds me of a suggested patch to fix warnings about ignoring
function results that should not be ignored:

[...]
+ int dummy;
[...]
- fwrite(str, 1, s - str, stdout);
+ dummy = fwrite(str, 1, s - str, stdout);
[...]
- fwrite(str, 1, s - str, stdout);
+ dummy = fwrite(str, 1, s - str, stdout);
[...]
- write (2, t, strlen((char *)t));
+ dummy = write (2, t, strlen((char *)t));

(et cetera)

The warnings are there for a reason, but some people don't seem to want to
understand that. Assigning the result to dummy shuts up the compiler, so
in their minds the problem has probably disappeared.
 
D

David Schwartz

When I see a cast like that, I assume a so-called programmer got a
warning message along the lines of "warning: bla bla conversion
without a cast", and promptly stuck a cast there without giving it a
second thought.  I see that happening all the time.

Then the cast still does its job. It highlights to the code reviewer
that there was a cast there and the original programmer may or may not
have ensured that the conversion is safe. In the absence of the cast,
your attention might never have been drawn to that issue.

DS
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top