Visual C++ ver 6.0 bug

  • Thread starter Johan Bengtsson P&L Automatik AB
  • Start date
J

Thread Starter

Johan Bengtsson P&L Automatik AB

Hello list

I have tried to migrate a program from Visual C++ version 4 to Visual C++ version 6 - and failed.

I pinpointed the failure down to the following error:

Several places make use of the ? operator in C in the following way:

a?b:c=d;

(this is a simplification of the actual code)
The idea is: depending on the value of a assign value d to either b or c. This is all following the definition of ANSI C and also following what is found in the help files provided with the compiler.

However the compiler treats this equally to:

a?b:(c=d);

ie if a is true nothing happens and if a is false c will get the value of d.
the value of d is not even evaluated if a is true.

There is a simple workaround to this by changing the code to:

(a?b:c)=d;

but I would of course not want to do that in some 1000+ places and possibly miss a few one (and thereby introducing bugs) but I will probably do it if no other solution is found.

Does anyone have any other information about this?
(I have reported this in a bug report to microsoft approx a year back but I have not seen anything about this from them so far)


/Johan Bengtsson

----------------------------------------
P&L, the Academy of Automation
Box 252, S-281 23 H{ssleholm SWEDEN
Tel: +46 451 49 460, Fax: +46 451 89 833
E-mail: [email protected]
Internet: http://www.pol.se/
----------------------------------------
 
M

Mark D. Chesney

I believe that the version 6.0 compiler's behavior is correct. The conditional expression is right-associative with respect to its first and
third operands, so that
a ? b : c ? d : e ? f : g
is interpreted as
a ? b : (c ? d : (e ? f : g))

This appears to be the default behavior that you are witnessing. Apparently the VC++ version 4 compiler was interpreting the statement incorrectly.

As a general rule, whenever there is any doubt, it is better to use too many parentheses than too few!

Mark Chesney
 
D

Darryl L. Palmer

Is it supposed to work, yes. Does it work, no. I guess you are stuck with writing a program to change it. For more assistance with microsoft
products join the microsoft.public.* newsgroups on your NNTP newsgroup server or go to the msnews.microsoft.com news server and join them there.

Darryl Palmer
Cleveland State University
 
I think both ways are incorrect. However, I tried the following code with several compilers on several platforms and this is what I got:
#include <stdio.h>

main()
{
int a = 1, b = 2, c= 3, d = 4;
a?b:c=d;
printf("a = %d, b = %d, c = %d, d = %d", a, b, c, d);
}

Visual C++ 5.0 on WinNT 4.0: does not compile neither as C nor as C++

gcc 2.7.2 (C) on Linux 2.0.36 (Intel): a = 1, b = 4, c = 3, d = 4
(This is the way you want it).

egcs (C++) on Linux 2.0.36 (Intel): a = 1, b = 2, c = 3, d = 4
(This is the way you do not want it).

cc (C) on OSF/1 (DEC Alpha): does not compile as C. (I do not have C++ in this platform).

I recommend you to rewrite everythig, but using the following idiom:
a?b=d:(c=d)
or, even better:
a?(b=d):(c=d)

This is valid C, valid C++ and compiles and behaves the same across all compliers/platforms.

I checked the gcc documentation and it states that its behavior is a non-standard "extension".

I hope this helps,

Guido Urdaneta
Applied Computing Institute
University of Zulia
 
P

Paul McGuire

>> Several places make use of the ? operator in C in the following way:
>>
>> a?b:c=d;
>>
>> (this is a simplification of the actual code)
>> The idea is: depending on the value of a assign value d to either b or c. This
>> is all following the definition of ANSI C and also following what is found in
>> the help files provided with the compiler.
>>
>> However the compiler treats this equally to:
>>
>> a?b:(c=d);
>>
>> ie if a is true nothing happens and if a is false c will get the value of d.
>> the value of d is not even evaluated if a is true.

Given the amount of explanation you have to go through, is this "clever coding" style really worth it?

If you had:

if ( a )
b = d;
else
c = d;

I should think most compilers would be able to figure this out and do the right thing, and you would have little need to document this arcane use of the '?' ternary operator. I'll bet the compiler will even optimize the code properly, and generate as tight assembly code as the original terse expression. (You'll also have an easier time training up any new hires in your support staff.)

Here's a compromise which may be more straightforward (warning - I have NOT
tested this, so verify it for yourself):

*( a ? &b : &c ) = d;

This too is is fairly obtuse, so I'm not overfond of it; but at least it's clear where the right and left hand sides of the '=' operator are.
Personally I'd still prefer the explicit if-then-else, but if you are trying to automate this, then the compromise may help.

I'm sorry this exists in 1000+ places, but sometimes it's worth it to go through and clean up coding practices which have turned out to be
problematic.

Good luck,

Paul McGuire
Objectspace Fab Solutions
Austin, Texas
- Advanced Process Control Solutions for the Semiconductor Industry -
 
J

John G. Boland

Paul McGuire writes:

<< if ( a )
b = d;
else
c = d;

I should think most compilers would be able to figure this out and do the right thing >>

I would PAY for the code above. I would NOT pay for this:

<< *( a ? &b : &c ) = d; >>

So:
Be clever
Be concise
Remember who's paying your invoice!

"Lurker John" G. Boland, president
VisiBit Corporation
 
J
Bravo Paul:

That's my least favorite construct in the C or C++ language. It falls under the "cute tricks" chapter.

Joe Bingham
 
W

Warren Postma

Quoth Joe Bingham:

> That's my least favorite construct in the C or C++ language. It falls
> under the "cute trick"s chapter.

Quoth someone else:
>> a?b:c=d;

Sounds like you wouldn't like Perl then, since it seems Perl only has Cute
Tricks, and weird operator-overload type behaviour is the predominant method
of getting things done.

Warren
 
J

John G. Boland

Dear list,

In the discussion of:

<< a?b:(c=d); >> or
<< (a?b:c)=d; >> versus
<< a?(b=d):(c=d) >>

...compiling (or not) and giving correct answers (or not), three more lines result in simple code:

if ( a )
b = d;
else
c = d;

...that (i) is pretty much self-documented and (ii) will compile (well, probably). The code *will* be easily understood and tested in six months, particularly if a, b, c, and d are complex.

"Lurker John" G. Boland, president
VisiBit Corporation
 
M
> three more lines
> result in simple code:
>
> if ( a )
> b = d;
> else
> c = d;

Simpler code, or code that a simple can understand? Of course the first examples are difficult to understand if one does not understand
(all of) the C language. So maybe we could write a new language, C--. Its like C, but doesn't have all the operators, like ?, +=, -=, etc. This way everyone has to write things out the long way so code is 'easy' to read.

> ...that (i) is pretty much self-documented and

I say yours is an example of undocumented code. Documation would be
comments like:

if ( a ) /* b converts density to baume */
> b = d; /* assign the formula for heavier/lighter than water soln's */

> else
> c = d;

>(ii) will
> compile (well,
> probably). The code *will* be easily understood and tested in
> six months,
> particularly if a, b, c, and d are complex.

Your implication is that the people who will be reading the code will not be well versed C. This is fine, however it should be made clear to the coder ahead of time, that "C--" should be used.

This topic seems to have hit a nerve with me. While I do see your point of making the code easier to read for the non-expert, it irritates me
when I see (other) people complaining that the code is not worth being paid for, when the code is correct, its not the complainers code, and the person responsible for the code understands it.

Mark Blunier
Any opinions expressed in this message are not necessarily those of the
company.
 
J

Johan Bengtsson

.... and the main reason for using the first syntax in the first place was readability, not for someone barely understanding C but for someone reading some 100000+ lines of code, where 3 lines extra at some 1000+ places and 10
lines extra at yet some 10000+ places and so on would make it less readable for anyone understanding the code...

Let's drop the subject entirely. I have got the answers I need and thank you all for giving them!

/Johan Bengtsson

----------------------------------------
P&L, the Academy of Automation
Box 252, S-281 23 H{ssleholm SWEDEN
Tel: +46 451 49 460, Fax: +46 451 89 833
E-mail: [email protected]
Internet: http://www.pol.se/
----------------------------------------
 
V

Vladimir Bunyakin

"Blunier, Mark" wrote:
>
> > In the discussion of:
> >
> > << a?b:(c=d); >> or
> > << (a?b:c)=d; >> versus
> > << a?(b=d):(c=d) >>
> >
> > ...compiling (or not) and giving correct answers (or not),
> > three more lines
> > result in simple code:
> >
> > if ( a )
> > b = d;
> > else
> > c = d;
>
> Simpler code, or code that a simple can understand? Of course the
> first examples are difficult to understand if one does not understand
> (all of) the C language. So maybe we could write a new language, C--.
> Its like C, but doesn't have all the operators, like ?, +=, -=, etc.
> This way everyone has to write things out the long way so code is 'easy' to
> read.

One simple question: is the idea of using a?b:c as an l-value smart?

...

--
Sincerely yours,
Vladimir Bunyakin.
 
On Thu, Jan 27, 2000 at 01:14:24PM +0200, Vladimir Bunyakin wrote:
>
> One simple question: is the idea of using a?b:c as an l-value smart?

That would have to depend on the context. Using any allowable construct that isn't immediately obvious to the uninitiated could be viewed in
as unwise, and that could include C's +=, ++, and any number of other common forms. The distinction is purely arbitrary IMHO, and if a?b:c
is valid as an lvalue, then there's no intrinsic reason to forbid it.

The question came up because the form was found to be unsupported by a version of a compiler where it formerly had been supported. Standard C
explicitly forbids a?b:c-as-lvalue, but at least some C++ implementations have allowed it.

A note in http://www.jcu.edu.au/docs/gnu/g++FAQ.html, "What's new in version 2.7.0 of gcc/g++" seems to indicate that the lvalue usage has recently been disallowed:

The parsing of expressions such as a ? b : c = 1 has changed from

(a ? b : c) = 1

to

a : b ? (c = 1).

This is a new C/C++ incompatibility brought to you by the ANSI/ISO
standards committee.

--
Ken Irving
Trident Software
[email protected]
 
Top