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

C

CBFalconer

David said:
.... snip ...

I had a function that used to return a bool (true=success or
false=failure). It was changed to return zero for success or an
error code on failure. One caller was not changed to reflect
this. It still read something like:

if(!FunctionThatNowReturnsInt(x))
{
// process error
}

GCC did not issue a warning. MVC did.

Hunh! What error/warning? The only thing of interest is whether
or not that function returns a zero. MVC is obviously wrong.
 
H

Harald van Dijk

Hunh! What error/warning? The only thing of interest is whether or not
that function returns a zero. MVC is obviously wrong.

Turn on your brain. There is absolutely nothing wrong with warning
messages for code constructs of arguably poor style. And by constructs of
arguably poor style, I mean constructs which some of Microsoft's customers
wish to avoid, regardless of how you feel about it.
 
J

James Kuyper

David said:
Since that code is broken, it should be prohibited. Consider:

#define PRINTER_ON 0x100
#define PRINTER_HAS_PAPER 0x200
#define PRINTER_NO_ERROR 0x400
#define ready (PRINTER_ON|PRINTER_HAS_PAPER|PRINTER_NO_ERROR)

Oops, now the printer is ready if it's on even if it has no paper.
That can't be right.

Martin's message did not identify what 'ready' was, referring to this
only as an idiom. You should assume, when given an example like this,
that the code being provided has a context that makes it reasonable,
unless no such context can exist. The context implied by this code is
that printer_state and ready are both unsigned integers, and 'ready'
has no more than a single bit set, and that this bit has a special
meaning when set in printer_state.

You might, with just as much justification, call it broken because it
would fail if 'ready' had a floating point type. People posting messages
here shouldn't have to provide the full context of a code fragment that
clearly implies all that needs to be known about the context.
 
D

David Schwartz

Martin's message did not identify what 'ready' was, referring to this
only as an idiom. You should assume, when given an example like this,
that the code being provided has a context that makes it reasonable,
unless no such context can exist. The context implied by this code is
that  printer_state and ready are both unsigned integers, and 'ready'
has no more than a single bit set, and that this bit has a special
meaning when set in printer_state.

Right, and seeing his code, you'd have to check all that or assume all
that. And, his code would break if the definition of 'ready' ever
changed, even though it doesn't make it clear that it depends on that
definition.

Is that totally unacceptable in any context? Of course not. Is it
worth saving a few bytes? No way. In other words, it is reasonable to
prohibit that idiom because its costs exceed its benefits.
You might, with just as much justification, call it broken because it
would fail if 'ready' had a floating point type. People posting messages
here shouldn't have to provide the full context of a code fragment that
clearly implies all that needs to be known about the context.

I would hope that the compile would generate a warning if 'ready' had
a floating point type.

DS
 
D

David Schwartz

Hunh!  What error/warning?  The only thing of interest is whether
or not that function returns a zero.  MVC is obviously wrong.

I don't have the exact warning handy, but the gist of it was that
there is an implicit cast from an integer to a boolean that has a
performance cost.

Now that I think about it, the '!' may not have been there.

I found another case where MVC issues a warning and GCC does not (at
least, at the development/debug warning levels I normally use). The
code was something like this:

template <typename T> static void numtostring(T n, char *buf)
{
if(n<0)
{
*buf++='-';
n=-n;
}
// ...
}

MSVC issues a warning when the class is instantiated with an unsigned
type. Clearly, the 'if' code is is a safe no-op for unsigned classes
and intended to do the right thing for signed classes.

This is a warning I have found no way to code around.

DS
 
M

Mateusz Loskot

David Schwartz said:
It would in ours, since our coding standards prohibit implicit
comparisons and specify that the negation operator can only be used on
boolean types. IMO, the two extra characters to make "x!=0" are well
worth it for the improved clarity of the code. For one thing, it makes
it clear that you know that x is an integer.


Zero does not indicate only integers, but x may be nullptr as well:

int* ptr = 0;
ptr = new int(10);
if (0 != ptr)
{
}

However, I agree that explicit 0 != comparison helps sometimes to for
fast recognition that operand is not-a-boolean, but ordinary type,
without checking declaration of variable. Explicit == no need for comments
as it's self-describing style. Personally, I prefer to test
pointers using Zero if (0 != ptr) over if(!ptr).

Best regards,
 
K

Kenny McCormack

David Schwartz said:
template <typename T> static void numtostring(T n, char *buf)
{
if(n<0)
{
*buf++='-';
n=-n;
}
// ...
}

MSVC issues a warning ...

(Channelling our good and reliable regs)

Danger! Danger! Panic!!! Bring in armed forces!!

Panic button pushed. C++ code posted in our pristine newsgroup!

Danger! Panic!
 
J

James Kuyper

Mateusz said:
Zero does not indicate only integers, but x may be nullptr as well:

int* ptr = 0;
ptr = new int(10);

This is comp.lang.c, not comp.lang.c++. nullptr and new are C++
keywords; they have no special meaning in C.
if (0 != ptr)

We do, however, have null pointer constants, as does C++. What qualifies
as a null pointer constant is different in both languages, but 0
qualifies as such in both. Therefore, the main thing you were trying to
say remains true: the fact that someting is being compared with 0
doesn't imply that it's an integer; it doesn't even imply that it has an
arithmetic type.
 
J

James Kuyper

Restoring context that has since been snipped (this is not a complaint,
I just need to refer to this context):
David Schwartz wrote: ....

David said:
I don't have the exact warning handy, but the gist of it was that
there is an implicit cast from an integer to a boolean that has a
performance cost.

Now that I think about it, the '!' may not have been there.

If the MSV diagnostic is triggered by the type of if-condition, that
must certainly be the case. As written, the type of the if-condition
would have been 'int' regardless of the type returned by the function.
In the rest of my response, I'll assume that it was not there.

The C standard allows diagnostics to be issued for any reason the
implementation wants, and does not mandate the truthfulness of the text
of those diagnostics (it doesn't even mandate they they be written in
any known language). However, as a user I prefer truthful diagnostics,
and that one isn't.

This code involves no casts. There's no such thing as an implicit cast,
only implicit conversions - a cast is an explicit conversion. The C
standard specifies no conversion to bool; only that the if-condition be
compared for equality with 0. In C++, there is indeed a conversion to
bool (6.4p4), but this message was posted to comp.lang.c, and in C there
is no such conversion.

Since 0 has an 'int' type, when FunctionsThatNowReturnsInt() returned
bool, performing that comparison would technically have required a
conversion from bool to int (though probably with no real performance
cost). Changing the return type to 'int' removed the need for a
conversion; it didn't create such a need.

....
template <typename T> static void numtostring(T n, char *buf)

Again, this is comp.lang.c: C++ templates are off-topic. I see that the
subject line is refers to VC++, which suggests that including
comp.lang.c rather than comp.lang.c++ may have been a mistake; but we do
receive inquiries on comp.lang.c about using VC++ with options that make
it a strictly C compiler, and until this morning's messages, that's what
I assumed was the case for this thread.
 
D

Default User

James said:
Mateusz Loskot wrote:

This is comp.lang.c, not comp.lang.c++. nullptr and new are C++
keywords; they have no special meaning in C.

It's also microsoft.public.vc.language.




Brian
 
J

jameskuyper

Default said:
It's also microsoft.public.vc.language.

Yes, but if the topic was using VC to compile C++ code, then it should
not be cross-posted to comp.lang.c, but to comp.lang.c++.
 
D

Default User

jameskuyper said:
Yes, but if the topic was using VC to compile C++ code, then it should
not be cross-posted to comp.lang.c, but to comp.lang.c++.

That's the fault of the OP. You can't really expect people in one group
to follow the dictates of another just because the message happens to
be crossposted. Which is a good reason for being VERY judicious in
cross-posting at all.



Brian
 
C

CBFalconer

James said:
Mateusz Loskot wrote:
.... snip ...


This is comp.lang.c, not comp.lang.c++. nullptr and new are C++
keywords; they have no special meaning in C.

Is it even C++? I don't use it, but I thought 'new' was a void
function in C++. I see this is crossed to a MS group, so maybe it
is another MS foulup.
 
C

CBFalconer

David said:
.... snip ...

I found another case where MVC issues a warning and GCC does not
(at least, at the development/debug warning levels I normally
use). The code was something like this:

template <typename T> static void numtostring(T n, char *buf)
{
if(n<0)
{
*buf++='-';
n=-n;
}
// ...
}

MSVC issues a warning when the class is instantiated with an
unsigned type. Clearly, the 'if' code is is a safe no-op for
unsigned classes and intended to do the right thing for signed
classes.

This is a warning I have found no way to code around.

This is not C, and thus is off-topic and of no interest on c.l.c.
 
K

Keith Thompson

CBFalconer said:
Is it even C++? I don't use it, but I thought 'new' was a void
function in C++. I see this is crossed to a MS group, so maybe it
is another MS foulup.

<OT>
No, "new" in C++ is a keyword, and the code above is perfectly correct
C++.
</OT>
 
J

jameskuyper

CBFalconer said:
Is it even C++? I don't use it, but I thought 'new' was a void
function in C++.

<OT in c.l.c>
In C++, new is an operator, not a function (though, like most other
operators, it can be overloaded with a user-defined function). A new-
expression has a value which is a pointer to the type specified by the
right operand of 'new'.

If you thought the result was void, how exactly did you expect it to
work?
</OT>
 
C

CBFalconer

jameskuyper said:
CBFalconer wrote:
.... snip ...


In C++, new is an operator, not a function (though, like most
other operators, it can be overloaded with a user-defined
function). A new- expression has a value which is a pointer to
the type specified by the right operand of 'new'.

If you thought the result was void, how exactly did you expect
it to work?

Mine was a question. I didn't expect it to work. In fact, I
usually don't expect code published here to work without polishing.
 
J

James Kuyper

CBFalconer said:
Mine was a question. I didn't expect it to work. In fact, I
usually don't expect code published here to work without polishing.

Sorry, I should have been clearer. I wasn't asking how you thought the
code works; I was wondering how you thought the C++ keyword 'new' works.
If you were under the impression that correct use of 'new' produced an
expression with a 'void' type, how did you imagine that C++ code gained
access to the object being allocated?
 
D

David Schwartz

Again, this is comp.lang.c: C++ templates are off-topic. I see that the
subject line is refers to VC++, which suggests that including
comp.lang.c rather than comp.lang.c++ may have been a mistake; but we do
receive inquiries on comp.lang.c about using VC++ with options that make
it a strictly C compiler, and until this morning's messages, that's what
I assumed was the case for this thread.

Only that last example was C++, and it's *not* off-topic. It's an
example that's helpful to illuminate the difference in behavior
between MSVC and GCC. These same difference also manifest in C code.
If an example from another language helps to understand a C language
construct or tool, it is most definitely on topic for c.l.c.

DS
 
D

David Schwartz

This is not C, and thus is off-topic and of no interest on c.l.c.

No. That is a mindless reflex that is both irritating and harmful.

We are trying to understand the difference between the warnings
generated by GCC and MSVC and understand the different philosophies
the control the warning generation in these two tools. We're most
interested in understanding the cases we don't know about and figuring
out what cases to test.

*Any* difference in any language is helpful for two reasons:

1) It helps to illuminate the philosophy of MSVC versus GCC. This same
philosophy animates their C warning choices.

2) It may suggest analogous C code that also shows the same
difference.

This is a case where we are very short on examples. Any example we
have, C or not, is valuable to understand the (both known and unknown)
C differences.

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

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top