[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Compiler bug in lcc-win32

thomas.mertes

7/17/2011 9:58:00 AM

Hello,

I discovered a compiler bug in lcc-win32 under Windows XP.
The || and && operators work wrong when -O is used.
The following program shows the bug:

-------------------- Begin file testlcc.c --------------------
/* Compile with:
* lc -O -g5 -A testlcc.c -o testlcc.exe
*/

#include "stdio.h"

typedef enum {ILLEGALCHAR, EOFCHAR, LETTERCHAR, DIGITCHAR,
UNDERLINECHAR, SHARPCHAR, QUOTATIONCHAR, APOSTROPHECHAR,
LEFTPARENCHAR, PARENCHAR, SPECIALCHAR, SPACECHAR,
NEWLINECHAR} charclass;

typedef int booltype;

charclass ch_class[256 - EOF];
booltype ch_op[256 - EOF];

#define char_class(CHARACTER) ch_class [((int)(CHARACTER)) - EOF]
#define op_char(CHARACTER) ch_op [((int)(CHARACTER)) - EOF]

void get_ident (unsigned char *name, unsigned int length)
{
printf("length:\n%d # should be: 1\n", length);
printf("name[0]:\n'%c' (%d) # should be: '$' (36)\n",
name[0], name[0]);
printf("op_char(name[0]):\n%d # should be: 1\n",
op_char(name[0]));
printf("char_class(name[0]):\n%2d # should be: 10\n",
char_class(name[0]));
printf("char_class(name[0])==LEFTPARENCHAR:\n");
printf("%d # should be: 0\n",
char_class(name[0])==LEFTPARENCHAR);
printf("op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR:\n");
printf("%d # should be: 1\n",
op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR);
printf("char_class(name[0])==PARENCHAR:\n");
printf("%d # should be: 0\n",
char_class(name[0])==PARENCHAR);
printf("op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR || "
"char_class(name[0])==PARENCHAR:\n");
printf("%d # should be 1\n",
op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR);
printf("length==1 && (op_char(name[0]) || "
"char_class(name[0])==LEFTPARENCHAR || "
"char_class(name[0])==PARENCHAR):\n");
printf("%d # should be 1\n",
length==1 && (op_char(name[0]) ||
char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR));
}

int main (int argc, char *argv[])
{
char_class('$') = SPECIALCHAR;
op_char('$') = 1;
get_ident("$", 1);
}
-------------------- End file testlcc.c --------------------

When I compile with

lc -O -g5 -A testlcc.c -o testlcc.exe

and start testlcc.exe, I get the following output:

length:
1 # should be: 1
name[0]:
'$' (36) # should be: '$' (36)
op_char(name[0]):
1 # should be: 1
char_class(name[0]):
10 # should be: 10
char_class(name[0])==LEFTPARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR:
0 # should be: 1
char_class(name[0])==PARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR:
0 # should be 1
length==1 && (op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
|| char_class(name[0])==PARENCHAR):
0 # should be 1

--------------------

The correct result can be obtained with gcc:

gcc testlcc.c -o testlcc

1 # should be: 1
name[0]:
'$' (36) # should be: '$' (36)
op_char(name[0]):
1 # should be: 1
char_class(name[0]):
10 # should be: 10
char_class(name[0])==LEFTPARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR:
1 # should be: 1
char_class(name[0])==PARENCHAR:
0 # should be: 0
op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR ||
char_class(name[0])==PARENCHAR:
1 # should be 1
length==1 && (op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
|| char_class(name[0])==PARENCHAR):
1 # should be 1

--------------------

I hope this helps to find and correct the compiler bug.


Greetings Thomas Mertes

--
Seed7 Homepage: http://seed7.sourc...
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.
31 Answers

James Kuyper

7/17/2011 12:39:00 PM

0

On 07/17/2011 05:58 AM, tm wrote:
> Hello,
>
> I discovered a compiler bug in lcc-win32 under Windows XP.

Why are you posting this here, instead of contacting the vendor
directly? It gives the (possibly correct) impression that your main
purpose is to embarrass the vendor, rather than simply getting the bug
fixed (assuming that it actually is a bug - I didn't bother to check).
Even if you were justified in making a big public issue about this,
comp.compilers.lcc would have been the more appropriate forum.

While I did not examine your code closely, I did notice one minor issue:
....
> #include "stdio.h"

That should be <stdio.h>; it can make a difference which one you use.

....
> lc -O -g5 -A testlcc.c -o testlcc.exe
....
> gcc testlcc.c -o testlcc

Keep in mind that, like most compilers, neither of the compilers that
you're comparing fully conforms to any version of the C standard in
their default mode. You haven't chosen the correct options to put gcc
into a fully conforming mode - you need to use at least -ansi -pedantic.
I'm not sure which options you should use with lcc, but whichever ones
they are, you should use them before comparing the results with gcc;
otherwise the comparison is meaningless.

--
James Kuyper

thomas.mertes

7/17/2011 4:46:00 PM

0

On 17 Jul., 14:39, James Kuyper <jameskuy...@verizon.net> wrote:
> On 07/17/2011 05:58 AM, tm wrote:
>
> > Hello,
>
> > I discovered a compiler bug in lcc-win32 under Windows XP.
>
> Why are you posting this here, instead of contacting the vendor
> directly?

Because jacob navia often discusses in this group.

[snip accusation]

It is not my intention to embarrass anybody.
A compiler is not a religion. Please calm down.

> While I did not examine your code closely, I did notice one minor issue:
> ...
>
> > #include "stdio.h"
>
> That should be <stdio.h>; it can make a difference which one you use.

For the purpose of showing this bug, this does not make
any difference.

[snip]

> You haven't chosen the correct options to put gcc
> into a fully conforming mode - you need to use at least -ansi -pedantic.

No, The expression

op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR

where name[0] is '$' and op_char('$') is 1, should
always return 1, independend of K&R, ANSI C89, ANSI C99
and probably also for a future version. The expression

1 || anyting

should always evaluate to 1, independend of C version
or compiler. Otherwise it is not C.

> I'm not sure which options you should use with lcc, but whichever ones
> they are, you should use them before comparing the results with gcc;
> otherwise the comparison is meaningless.

I do not agree. See above.


Greetings Thomas Mertes

--
Seed7 Homepage: http://seed7.sourc...
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.

Eric Sosman

7/17/2011 5:45:00 PM

0

On 7/17/2011 12:46 PM, tm wrote:
> [...]The expression
>
> 1 || anyting
>
> should always evaluate to 1, independend of C version
> or compiler. Otherwise it is not C.

No matter: Neither is your program. Once you invoke undefined
behavior, the implementation is not obliged to live up to anything
the C Standard promises.

I grant that the particular instances of undefined behavior (two)
and of implementation-defined behavior (one) are extremely unlikely
to be responsible for the results you report. Nonetheless, the claim
"Frobozz Magic C doesn't treat my buggy program the way I want, ergo
Frobozz Magic C is at fault" is a bit of a stretch.

>> I'm not sure which options you should use with lcc, but whichever ones
>> they are, you should use them before comparing the results with gcc;
>> otherwise the comparison is meaningless.
>
> I do not agree. See above.

Any implementation conforming to C90 or to C99 is required to
issue diagnostics for your code. Have you complained to the gcc
folks about their compiler's failure to do so?

--
Eric Sosman
esosman@ieee-dot-org.invalid

thomas.mertes

7/17/2011 6:24:00 PM

0

On 17 Jul., 19:44, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 7/17/2011 12:46 PM, tm wrote:
>
> > [...]The expression
>
> > 1 || anyting
>
> > should always evaluate to 1, independend of C version
> > or compiler. Otherwise it is not C.
>
>      No matter: Neither is your program.

Would you please be so kindly to explain, where did I
invoke undefined behavior.

AFAIK. The if-statement

if (1 || sub_expression)
print("TRUE\n");

should print TRUE. Why should this be invoke undefined
behavior?

To state it clear:

**** LCC FAILS TO WRITE TRUE WITH THIS IF STATEMENT ****

[snip]

I think the next time I will not spend my time to
examine a compiler bug, write a test program and
tell about it. I will just refuse to use that compiler.


Greetings Thomas Mertes

--
Seed7 Homepage: http://seed7.sourc...
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.

thomas.mertes

7/17/2011 6:37:00 PM

0

On 17 Jul., 20:23, tm <thomas.mer...@gmx.at> wrote:
> On 17 Jul., 19:44, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
>
> > On 7/17/2011 12:46 PM, tm wrote:
>
> > > [...]The expression
>
> > > 1 || anyting
>
> > > should always evaluate to 1, independend of C version
> > > or compiler. Otherwise it is not C.
>
> >      No matter: Neither is your program.
>
> Would you please be so kindly to explain, where did I
> invoke undefined behavior.
>
> AFAIK. The if-statement
>
> if (1 || sub_expression)
>   print("TRUE\n");

Before some nitpicker shows up. This should be:

if (1 || sub_expression)
printf("TRUE\n");

> should print TRUE. Why should this be invoke undefined
> behavior?

And this should be:

Why should this invoke undefined behavior?

> To state it clear:
>
> **** LCC FAILS TO WRITE TRUE WITH THIS IF STATEMENT ****
>
> [snip]
>
> I think the next time I will not spend my time to
> examine a compiler bug, write a test program and
> tell about it. I will just refuse to use that compiler.
>
> Greetings Thomas Mertes
>
> --
> Seed7 Homepage:  http://seed7.sourc...
> Seed7 - The extensible programming language: User defined statements
> and operators, abstract data types, templates without special
> syntax, OO with interfaces and multiple dispatch, statically typed,
> interpreted or compiled, portable, runs under linux/unix/windows.

jacob navia

7/17/2011 7:04:00 PM

0

Hi Thomas

Thank you for your bug report.

I am unable to fix it right now because I am in holidays at the beach in
Grière plage, Vandée. (Atlantic coast of France)

It is nice here, wind, sea, sun, kids, ice-cream, swimming pool, no
internet connection, I have to go to some cyber cafe to get one...

Will fix it later.

jacob


thomas.mertes

7/17/2011 7:13:00 PM

0

On 17 Jul., 21:04, jacob navia <ja...@spamsink.net> wrote:
> Hi Thomas
>
> Thank you for your bug report.
>
> I am unable to fix it right now because I am in holidays at the beach in
> Gri re plage, Vand e. (Atlantic coast of France)

Enjoy your holidays.

> It is nice here, wind, sea, sun, kids, ice-cream, swimming pool, no
> internet connection, I have to go to some cyber cafe to get one...
>
> Will fix it later.

No problem. I hope that my testprogram is helpful.
I examined the problem for two days and almost gave up...


Greetings Thomas Mertes

--
Seed7 Homepage: http://seed7.sourc...
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.

Eric Sosman

7/17/2011 7:27:00 PM

0

On 7/17/2011 2:23 PM, tm wrote:
> On 17 Jul., 19:44, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>> On 7/17/2011 12:46 PM, tm wrote:
>>
>>> [...]The expression
>>
>>> 1 || anyting
>>
>>> should always evaluate to 1, independend of C version
>>> or compiler. Otherwise it is not C.
>>
>> No matter: Neither is your program.
>
> Would you please be so kindly to explain, where did I
> invoke undefined behavior.

Run the compiler(s) in a conforming mode, and they'll tell you
about one instance of U.B. (the diagnostic is required). I don't
know about lcc, but gcc will tell you about the other instance, too,
if you ask it politely. The instance of implementation-defined
behavior has already been brought to your attention. (It occurs
to me that there are other instances of I-D behavior in your code,
but they're of the extremely far-fetched and nit-picky variety.)

--
Eric Sosman
esosman@ieee-dot-org.invalid

Keith Thompson

7/17/2011 8:19:00 PM

0

tm <thomas.mertes@gmx.at> writes:
[...]
> To state it clear:
>
> **** LCC FAILS TO WRITE TRUE WITH THIS IF STATEMENT ****
>
> [snip]
>
> I think the next time I will not spend my time to
> examine a compiler bug, write a test program and
> tell about it. I will just refuse to use that compiler.

Why on Earth would you say that?

Nobody is criticizing you for reporting a bug. Reporting bugs is A
Good Thing. We're just suggesting that a newsgroup (comp.lang.c)
that discusses a programming language is not the best place to do
it, since you're not really talking about the language. Especially
since there's a newsgroup, comp.compilers.lcc that discusses that
particular compiler (both lcc-win32 and the original lcc), and
because it would make more sense to contact the author direction.
Yes, jacob regularly posts here; I'm sure he reularly reads his
e-mail.

It's not even that big a deal. We get a lot of off-topic posts in
clc; yours is far from the worst. Why are you overreacting like
this to the simple suggestion that there are better places for
bug reports?

(Yes, this is cross-posted to a more appropriate newsgroup, but the
original post, and most of the discussion, were just in clc.)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

James Kuyper

7/17/2011 8:44:00 PM

0

On 07/17/2011 12:46 PM, tm wrote:
> On 17 Jul., 14:39, James Kuyper <jameskuy...@verizon.net> wrote:
>> On 07/17/2011 05:58 AM, tm wrote:
>>
>>> Hello,
>>
>>> I discovered a compiler bug in lcc-win32 under Windows XP.
>>
>> Why are you posting this here, instead of contacting the vendor
>> directly?
>
> Because jacob navia often discusses in this group.

Yes, and so do a few people who regularly post bug reports against lcc,
not too dissimilar from yours, for the sole apparent purpose of baiting
jacob into an intemperate response. A hallmark of those reports is that
the "bug" usually depends in some subtle fashion upon some
well-documented extension to C supported by lcc-win32. I don't know
lcc-win32's extensions well-enough to be sure that your code has not run
afoul of one of them.

>> While I did not examine your code closely, I did notice one minor issue:
>> ...
>>
>>> #include "stdio.h"
>>
>> That should be <stdio.h>; it can make a difference which one you use.
>
> For the purpose of showing this bug, this does not make
> any difference.

Until you know what caused the bug, you can't be sure. An incompatible
file named stdio.h in a location that is searched when you use "", but
is not searched when you use <>, could in principle be the reason why
printf() doesn't print the value you expected it to print. I consider
this extremely unlikely, which is why I labeled it a "minor issue", but
I still recommend correcting it.

>> You haven't chosen the correct options to put gcc
>> into a fully conforming mode - you need to use at least -ansi -pedantic.
>
> No, The expression
>
> op_char(name[0]) || char_class(name[0])==LEFTPARENCHAR
>
> where name[0] is '$' and op_char('$') is 1, should
> always return 1, independend of K&R, ANSI C89, ANSI C99
> and probably also for a future version. The expression

But in their default modes, like most other compilers, neither of those
compilers implements any of the languages you listed, so even if you're
right about those four languages, that doesn't guarantee that you're
right about the default lcc-win32 or gnu versions of C. Keep in mind,
also, that the problem could be in some entirely different part of the
code. It might not be the implementation of || that is producing
unexpected results, but a problem elsewhere in your code that manifests
itself in this location.

> 1 || anyting
>
> should always evaluate to 1, independend of C version
> or compiler. Otherwise it is not C.

That depends upon how you define "C"; jacob's definition is more
flexible than mine, but I doubt that lcc-win32 deliberately implements
|| in a way significantly incompatible with the requirements of the C
standard. However, it's quite possible that some other aspect of your
program is causing these symptoms.
--
James Kuyper