By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,852 Members | 2,240 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,852 IT Pros & Developers. It's quick & easy.

worst.c - foolishness

P: n/a
Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */

#define EOF -1
#define stdin 0

main()
{
int x, y;
char c;
char *fmt = "%d, %l";
unsigned int z;

while (!feof()) {
c = getchar();
if (EOF == c) continue;
}
gets(&c);
printf(fmt, &c, x);
fflush(stdin);
fmt = (char *)malloc(123);
fmt = (char *)realloc(fmt, 245);
y = fmt[1000];
for (z = 10; z >=0; z--) x += z;
if (z > 0) return -1;
} /* worst main */

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #1
Share this Question
Share on Google+
29 Replies


P: n/a
On Mon, 12 Jan 2004, CBFalconer wrote:
Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */

#define EOF -1
#define stdin 0

main()
You define main like this yet it's not recursive?

{
int x, y;
char c;
char *fmt = "%d, %l";
Just fmt? What's the type of fmt?

unsigned int z;

while (!feof()) {
While what? Always prefer an explicit comparision.

c = getchar();
Casting this one makes a better impression.

if (EOF == c) continue;
}
gets(&c);
printf(fmt, &c, x);
fflush(stdin);
fmt = (char *)malloc(123);
fmt = (char *)realloc(fmt, 245);
y = fmt[1000];
for (z = 10; z >=0; z--) x += z;
I'd try something that involves swapping..

if (z > 0) return -1;
} /* worst main */

Nov 14 '05 #2

P: n/a


On Mon, 12 Jan 2004, CBFalconer wrote:

Presented without further comment for "improvement"
Added comments inline; re-copied the new and "improved" version
at the bottom of this post.
/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */

#define EOF -1
#define stdin 0

main()
{
int x, y;
char c;
char *fmt = "%d, %l";
These two lines should probably be combined. Note the subtle change
in the indentation, also.

char *fmt = "%d, %l", c;
unsigned int z;

while (!feof()) {
Surely you meant

while (!feof(stdin)) {

This will avoid the warnings from those so-called "smarter" compilers. :)
c = getchar();
I agree with Jarno; haven't you learned about the return type of
getchar() yet? This line should, of course, read

c = (int)getchar();
if (EOF == c) continue;
}
You're missing a

scanf("%d", z);

here.
gets(&c);
printf(fmt, &c, x);
fflush(stdin);
fmt = (char *)malloc(123);
fmt = (char *)realloc(fmt, 245);
Why are you *assigning* the result of the 'realloc' call here?
Wouldn't it suffice to write

(void)realloc(&fmt, 245);

This also avoids that nasty memory leak.
y = fmt[1000];
for (z = 10; z >=0; z--) x += z;
if (z > 0) return -1;
} /* worst main */

== worst.c Revised Version ==

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */

/* Extra evilness, plus bonus bug, added by AJO. My gcc
complains about the use of 'gets', though */

#define EOF -1
#define stdin 0

main()
{
int x, y;
char *fmt = "%d, %l", c;
unsigned int z;

while (!feof(stdin)) {
c = (int)getchar();
if (EOF == c) continue;
}

scanf("%d", z);
gets(&c);
printf(fmt, &c, x);
fflush(stdin);

fmt = (char *)malloc(123);
(void)realloc(&fmt, 245);
y = fmt[1000];

for (z = 10; z >=0; z--) /* Add up some positive numbers
x += z; from 0 to 10 */

printf("%ul", (unsigned long)z);

if (z > 0) return -1;
} /* worst main */
-Arthur
[Disclaimer: ALL OF THE ABOVE IS A JOKE. IT IS EVIL AND WRONG
AND BAD, AND MUST NOT BE TAKEN SERIOUSLY.]
Nov 14 '05 #3

P: n/a
On Tue, 13 Jan 2004 04:46:05 +0200, Jarno A Wuolijoki
<jw******@cs.Helsinki.FI> wrote in comp.lang.c:
On Mon, 12 Jan 2004, CBFalconer wrote:
Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */

#define EOF -1
#define stdin 0

main()
You define main like this yet it's not recursive?


Of course it is recursive. main() always is in C.

{
int x, y;
char c;
char *fmt = "%d, %l";
Just fmt? What's the type of fmt?


Pointer to char. How did you miss that?
unsigned int z;

while (!feof()) {
While what? Always prefer an explicit comparision.


This is an explicit comparison. It is an explicit comparison of the
int value returned by feof() with 0, the result then negated.
c = getchar();


Casting this one makes a better impression.

if (EOF == c) continue;
}
gets(&c);
printf(fmt, &c, x);
fflush(stdin);
fmt = (char *)malloc(123);
fmt = (char *)realloc(fmt, 245);
y = fmt[1000];
for (z = 10; z >=0; z--) x += z;


I'd try something that involves swapping..

if (z > 0) return -1;
} /* worst main */


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #4

P: n/a
On Tue, 13 Jan 2004 04:09:45 GMT, Jack Klein <ja*******@spamcop.net>
wrote in comp.lang.c:
On Tue, 13 Jan 2004 04:46:05 +0200, Jarno A Wuolijoki
<jw******@cs.Helsinki.FI> wrote in comp.lang.c:
On Mon, 12 Jan 2004, CBFalconer wrote:
Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */

#define EOF -1
#define stdin 0

main()


You define main like this yet it's not recursive?


Of course it is recursive. main() always is in C.

{
int x, y;
char c;
char *fmt = "%d, %l";


Just fmt? What's the type of fmt?


Pointer to char. How did you miss that?
unsigned int z;

while (!feof()) {


While what? Always prefer an explicit comparision.


This is an explicit comparison. It is an explicit comparison of the
int value returned by feof() with 0, the result then negated.


....that is, assuming it returns a value since it invokes undefined
behavior by omitting the required FILE * argument.

c = getchar();


Casting this one makes a better impression.

if (EOF == c) continue;
}
gets(&c);
printf(fmt, &c, x);
fflush(stdin);
fmt = (char *)malloc(123);
fmt = (char *)realloc(fmt, 245);
y = fmt[1000];
for (z = 10; z >=0; z--) x += z;


I'd try something that involves swapping..

if (z > 0) return -1;
} /* worst main */

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #5

P: n/a

On Tue, 13 Jan 2004, Jack Klein wrote:

On Tue, 13 Jan 2004 04:46:05 +0200, Jarno A Wuolijoki wrote:
On Mon, 12 Jan 2004, CBFalconer wrote:
Presented without further comment for "improvement" ^^^^^^^^^^^^^ /* The objective here is to include as many C errors as ^^^^^^^^^^^^^ possible, without triggering the compiler into objecting.
while (!feof()) {


While what? Always prefer an explicit comparision.


This is an explicit comparison. It is an explicit comparison of the
int value returned by feof() with 0, the result then negated.


I do believe all of Jarno's questions were rhetorical, albeit
not very well-formed (English not being his first language). Obviously,
to conform to Chuck's "improvement" metric, main() should call itself,
something should be done about the type of fmt, and the above line
should be re-written

while (feof() != TRUE) {

for some suitable value of TRUE, to provide the "explicit comparison."
(Yes, that introduces an additional bug to the three already present
in that line. That's the point.)

;-)
-Arthur,
explaining a joke always makes it funnier
Nov 14 '05 #6

P: n/a
Jarno A Wuolijoki wrote:
On Mon, 12 Jan 2004, CBFalconer wrote:

main()

You define main like this yet it's not recursive?


Of course it's recursive. What obscure point are you trying to make?
char *fmt = "%d, %l";

Just fmt? What's the type of fmt?


It sure looks like it's a pointer to char ("char *"), doesn't it? What
obscure point are you trying to make?

while (!feof()) {

While what? Always prefer an explicit comparision.


Why? That would neither add or detract from CBF's avowed intent of writing
truly awful code that could slip past a compiler, although he is using his
with warnings almost disabled. Your advice sucks, but if you can't read
straight-forward C, by all means engage in typing practice.


--
Martin Ambuhl
Nov 14 '05 #7

P: n/a
On Mon, 12 Jan 2004 22:41:11 -0500, Arthur J. O'Dwyer wrote:


On Mon, 12 Jan 2004, CBFalconer wrote:

Presented without further comment for "improvement"
Added comments inline; re-copied the new and "improved" version
at the bottom of this post.
/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.
I have tried for at least one error per line. However
some variable declarations remain completely valid */


for (z = 10; z >=0; z--) /* Add up some positive numbers
x += z; from 0 to 10 */
You missed a semicolon. All lines should have a terminating semicolon,
right? So that should be:

for (z = 10; z >=0; z--); /* Adds up some positive numbers
x += z; from 0 to 10 */

-Arthur
[Disclaimer: ALL OF THE ABOVE IS A JOKE. IT IS EVIL AND WRONG
AND BAD, AND MUST NOT BE TAKEN SERIOUSLY.]


--
NPV

"the large print giveth, and the small print taketh away"
Tom Waits - Step right up

Nov 14 '05 #8

P: n/a
Jack Klein wrote:
Jack Klein <ja*******@spamcop.net> wrote in comp.lang.c:
<jw******@cs.Helsinki.FI> wrote in comp.lang.c:
On Mon, 12 Jan 2004, CBFalconer wrote:
.... snip ... > unsigned int z;
>
> while (!feof()) {

While what? Always prefer an explicit comparision.


This is an explicit comparison. It is an explicit comparison of
the int value returned by feof() with 0, the result then negated.


...that is, assuming it returns a value since it invokes undefined
behavior by omitting the required FILE * argument.


You forget the objective is to make errors without having the
compiler complain. With no #include and no feof() prototype there
is no required argument and no complaint.

I specified the compiler and commands to use. I couldn't use void
main without triggering something elsewhere. There is actually
some value to this, because it alerts you to the sort of thing
that you won't get warnings for.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #9

P: n/a
Nils Petter Vaskinn <no@spam.for.me.invalid> wrote in
news:pa***************************@spam.for.me.inv alid:
for (z = 10; z >=0; z--) /* Add up some positive numbers
x += z; from 0 to 10 */


You missed a semicolon. All lines should have a terminating semicolon,
right? So that should be:

for (z = 10; z >=0; z--); /* Adds up some positive numbers
x += z; from 0 to 10 */\


You're joking right? the semi-colon makes the for loop stand apart from
the statement x += z;

for (x = 0; x < 10; x++)
y = 0;

is a (IMHO) sloppy short-hand for

for (x = 0; x < 10; x++)
{
y = 0;
}

--
- Mark ->
--
Nov 14 '05 #10

P: n/a
In article <Xn********************************@130.133.1.4> ,
no****@embeddedfw.com says...
Nils Petter Vaskinn <no@spam.for.me.invalid> wrote in
news:pa***************************@spam.for.me.inv alid:
for (z = 10; z >=0; z--) /* Add up some positive numbers
x += z; from 0 to 10 */


You missed a semicolon. All lines should have a terminating semicolon,
right? So that should be:

for (z = 10; z >=0; z--); /* Adds up some positive numbers
x += z; from 0 to 10 */\


You're joking right?


Did you miss the part where this code is INTENTIONALLY bad?

--
Randy Howard
2reply remove FOOBAR

Nov 14 '05 #11

P: n/a
On Tue, 13 Jan 2004, Martin Ambuhl wrote:
Jarno A Wuolijoki wrote:
On Mon, 12 Jan 2004, CBFalconer wrote:
main() You define main like this yet it's not recursive?

Of course it's recursive. What obscure point are you trying to make?


It doesn't explicitly call itself. This is a grand win since you are
empowered to pass it whatever arguments you wish.

char *fmt = "%d, %l";

Just fmt? What's the type of fmt?

It sure looks like it's a pointer to char ("char *"), doesn't it? What
obscure point are you trying to make?


Ah, sorry. Sure it's type is pointer to char, but I was really after
the kind of content it's trying to represent. Your confusion here shows
precisely why hungarian notation is so important.
Moreover, since the format may be used in other parts of the program
I'd suggest making it a global.

while (!feof()) {

While what? Always prefer an explicit comparision.

Why? That would neither add or detract from CBF's avowed intent of writing
truly awful code that could slip past a compiler, although he is using his
with warnings almost disabled.


How do you know what value feof returns at the end? The code doesn't
spell it out loud. See?

Your advice sucks, but if you can't read
straight-forward C, by all means engage in typing practice.


Great advice, I've heard that RBTL is overrated these days anyway.

Nov 14 '05 #12

P: n/a
On Tue, 13 Jan 2004 08:16:29 -0600, Randy Howard wrote:
In article <Xn********************************@130.133.1.4> ,
no****@embeddedfw.com says...
Nils Petter Vaskinn <no@spam.for.me.invalid> wrote in
news:pa***************************@spam.for.me.inv alid:
>> for (z = 10; z >=0; z--) /* Add up some positive numbers
>> x += z; from 0 to 10 */
>
> You missed a semicolon. All lines should have a terminating semicolon,
> right? So that should be:
>
> for (z = 10; z >=0; z--); /* Adds up some positive numbers
> x += z; from 0 to 10 */\


You're joking right?


Did you miss the part where this code is INTENTIONALLY bad?


Well at least he spotted the error when he thought it was serious. But the
other equally sinister error which he missed (as did I at first) is the
failure to close the comment (it'll stand out in a syntax highlighting
editor, but gcc remains quiet).

Since logical errors count too I guess we could improve thee code more by
changing it to:

for (z = 10; z > 1; z--); /* Adds up some positive numbers
x += z; from 1 to 10 */\

--
NPV

"the large print giveth, and the small print taketh away"
Tom Waits - Step right up

Nov 14 '05 #13

P: n/a
Mark A. Odell wrote:
Nils Petter Vaskinn wrote:
You missed a semicolon. All lines should have a terminating semicolon,
right? So that should be:

for (z = 10; z >=0; z--); /* Adds up some positive numbers
x += z; from 0 to 10 */

You're joking right?


Your irony detector needs to be adjusted.

Nov 14 '05 #14

P: n/a

On Tue, 13 Jan 2004, Nils Petter Vaskinn wrote:

On Tue, 13 Jan 2004 08:16:29 -0600, Randy Howard wrote:
Nils Petter Vaskinn <no@spam.for.me.invalid> wrote
[Arthur wrote:]
>> for (z = 10; z >=0; z--) /* Add up some positive numbers
>> x += z; from 0 to 10 */
>
> You missed a semicolon. All lines should have a terminating semicolon,
> right? So that should be:
>
> for (z = 10; z >=0; z--); /* Adds up some positive numbers
> x += z; from 0 to 10 */\

You're joking right?
Did you miss the part where this code is INTENTIONALLY bad?


Well at least he spotted the error when he thought it was serious. But the
other equally sinister error which he missed (as did I at first)


MUHAHAHAHA! MUHAHAHAHA! MUHAHA... well, anyway...
That's one of my favorite intentionally-bad bugs, even though
I've never actually seen it anywhere except intentionally obfuscated
code.
is the
failure to close the comment (it'll stand out in a syntax highlighting
editor, but gcc remains quiet).

Since logical errors count too I guess we could improve thee code more by
changing it to:
ITYM "improve /thy/ code more..." ;-)
for (z = 10; z > 1; z--); /* Adds up some positive numbers
x += z; from 1 to 10 */\


This change removes one of the bugs that was already present -- the
infinite loop on the value of z (which by definition is always >= 0).
Of course, my changes removed the infinite loop, too, by returning
from main inside the loop -- but still I think the comparison of an
unsigned value against 0 is a big enough bug that it should remain
intact.
Oh, and what's the deal with the extra backslash at the end of the
line? Is that a newsreader artifact, or a potential bug I'm just not
seeing?

-Arthur
Nov 14 '05 #15

P: n/a
Grumble <in*****@kma.eu.org> wrote in
news:bu**********@news-rocq.inria.fr:
You missed a semicolon. All lines should have a terminating semicolon,
right? So that should be:

for (z = 10; z >=0; z--); /* Adds up some positive numbers
x += z; from 0 to 10 */

You're joking right?


Your irony detector needs to be adjusted.


Oh, sorry.

--
- Mark ->
--
Nov 14 '05 #16

P: n/a
On Mon, 12 Jan 2004, Arthur J. O'Dwyer wrote:
main()
{
int x, y;
char c;
char *fmt = "%d, %l";


These two lines should probably be combined. Note the subtle change
in the indentation, also.
char *fmt = "%d, %l", c;


ITYM
char* fmt = "%d, %l", c;
It would be better though if c was somehow used as if it were a char* instead.
Otherwise it just adds up to obfuscation.

unsigned int z;
while (!feof()) {

Surely you meant
while (!feof(stdin)) {
This will avoid the warnings from those so-called "smarter" compilers. :)


Dunno, it's one bug less if you ignore the misdefinition..

c = getchar();

I agree with Jarno; haven't you learned about the return type of
getchar() yet? This line should, of course, read
c = (int)getchar();


I was after char, to shut up those "smarter" compilers that warn about
lossy conversions. Apparently gcc isn't one of them though.

if (EOF == c) continue;
}


You're missing a
scanf("%d", z);
here.
gets(&c);
My linker warns about gets so I'd fuse these two into one scanf. You
can use c as if it was a pointer there too.

printf(fmt, &c, x);
fflush(stdin);
fmt = (char *)malloc(123);
fmt = (char *)realloc(fmt, 245);


Why are you *assigning* the result of the 'realloc' call here?
Wouldn't it suffice to write

(void)realloc(&fmt, 245);

This also avoids that nasty memory leak.
y = fmt[1000];
for (z = 10; z >=0; z--) x += z;


for (z = sizeof fmt; z>=0; z--) for (zz = z; z>=0; zz--);
if (fmt[z]-fmt[zz]<=0) fmt[z] ^= fmt[zz] ^= fmt[z] ^= fmt[zz];

...before mallocation of course, to sort the string constant.
#define EOF -1
#define stdin 0
#define swap(__a, __b) (__a ^= __b ^= __a ^= __b)

char* strfmt = "%d, %l", strtmp;

main()
{
int x, y;
char c;
unsigned z, zz;

while (feof()==EOF) {
c = (char) getchar();
if (c<0) continue;
}
scanf("%d%s", z, strtmp);
printf(strfmt, strtmp, x);
fflush(stdin);
for (z = sizeof strfmt; z>=0; z--) for (zz = z; z>=0; zz--);
if (strfmt[z]-strfmt[zz] <= 0) swap(strfmt[z], strfmt[zz]);
strfmt = (char*) malloc(123);
(void) realloc(&strfmt, 245);
y = strfmt[1000];
if (z>0) return -1;
else return main(42.7f);
}
Nov 14 '05 #17

P: n/a
Jarno A Wuolijoki wrote:

#define swap(__a, __b) (__a ^= __b ^= __a ^= __b)


Given its lack of protective parentheses, and multiple uses
of each argument, this just cries out for buggy usage later:

swap(strfmt[z++], c+d);

Needs some work to avoid syntax errors (e.g., invalid lvalue in
assignment), but this is a category of errors that is otherwise
untapped by this example.

- Larry
Nov 14 '05 #18

P: n/a
>> #define swap(__a, __b) (__a ^= __b ^= __a ^= __b)

Given its lack of protective parentheses, and multiple uses
of each argument, this just cries out for buggy usage later:

swap(strfmt[z++], c+d);

Needs some work to avoid syntax errors (e.g., invalid lvalue in
assignment), but this is a category of errors that is otherwise
untapped by this example.


Earlier in this newsgroup (many months away), it was said that
compilers may optimize things like

int tmp;
tmp = b;
b = a;
a = tmp;

away (i.e. to XCHG instruction), however they might not actually do so
with a ^= b ^= a ^= b; but replace it with a fistload of XOR operations.
--
Jan Engelhardt
Nov 14 '05 #19

P: n/a
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.


Wrong compilation command. You're asking gcc to treat worst.c as a
GNU C program, NOT as a C program. You really need -ansi -pedantic
if you want to be sure that your code doesn't contain errors that a
C compiler MUST diagnose. Trivial example:

fangorn:~/tmp 69> cat test.c
main() { return sizeof(void); }
fangorn:~/tmp 70> gcc test.c
fangorn:~/tmp 71> gcc -ansi -pedantic test.c
test.c: In function `main':
test.c:1: warning: sizeof applied to a void type

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #20

P: n/a

On Tue, 13 Jan 2004, Jarno A Wuolijoki wrote:

On Mon, 12 Jan 2004, Arthur J. O'Dwyer wrote:
char *fmt = "%d, %l";
These two lines should probably be combined. Note the subtle change
in the indentation, also.
char *fmt = "%d, %l", c;


ITYM
char* fmt = "%d, %l", c;


My mistake. ;-)
It would be better though if c was somehow used as if it were a
char* instead. Otherwise it just adds up to obfuscation.
I think you'd have trouble avoiding a compiler warning in that case.
unsigned int z;
while (!feof()) {

Surely you meant
while (!feof(stdin)) {
This will avoid the warnings from those so-called "smarter" compilers. :)


Dunno, it's one bug less if you ignore the misdefinition..


How so? My change merely replaces "undefined behavior upon calling
unprototyped function with wrong arguments" (which Chuck already had
elsewhere) with "undefined behavior upon passing NULL to feof()". Plus,
my bug is much subtler.

if (EOF == c) continue;
}


You're missing a
scanf("%d", z);
here.
gets(&c);


My linker warns about gets so I'd fuse these two into one scanf. You
can use c as if it was a pointer there too.


Doesn't that remove the bug, though? scanf("%d%s", z, &c) will
most likely try to store a string in the memory pointed to by &c
(invoking undefined behavior on buffer overrun); but the bug I was
trying to introduce there was that

scanf("%d", &foo);
gets(bar);

will store a number in 'foo', and then, assuming the user has pressed
'Return' to end that line of input, will proceed to read and discard
a single newline. OTOH, the gets() doesn't actually have a bug then;
it will store only a single '\0', won't it? So maybe keep that gets(),
but introduce the

scanf("%d", &foo);
fgets(&c, sizeof &c, stdin);

bug(s) elsewhere in the code. [Bugs include lack of prototype for
fgets, causing undefined behavior when passing literal 0 as third
argument; mis#defined 'stdin' that causes the literal 0 in the first
place; passing NULL to fgets in the first place; buffer overflow;
abuse of the 'sizeof' operator; lack of error-checking on scanf;
and the above-mentioned mishandling of possible newline characters
in the input.]

#define EOF -1
#define stdin 0
#define swap(__a, __b) (__a ^= __b ^= __a ^= __b)

char* strfmt = "%d, %l", strtmp;

main()
{
int x, y;
char c;
unsigned z, zz;

while (feof()==EOF) {
I think the use of == for != is too blatant a mistake. But it
occurs to me that we haven't misused De Morgan's Rule yet; we need
something along the lines of

while (feof()!=EOF || c=(int)getchar() != EOF) {

[I like my cast better than yours. Yours is only designed to
placate the compiler, AFAICT; mine has the "good" intention of
making sure the result of getchar() is wide enough to hold 'EOF'
before assignment to c. ;-) ]
c = (char) getchar();
if (c<0) continue;
}
scanf("%d%s", z, strtmp);
printf(strfmt, strtmp, x);
fflush(stdin);
for (z = sizeof strfmt; z>=0; z--) for (zz = z; z>=0; zz--);
if (strfmt[z]-strfmt[zz] <= 0) swap(strfmt[z], strfmt[zz]);
strfmt = (char*) malloc(123);
(void) realloc(&strfmt, 245);
y = strfmt[1000];
if (z>0) return -1;
else return main(42.7f);
}


Finally, it occurs to me that we haven't abused 'goto' yet, nor
attempted to 'switch' on some inappropriate type. Nor even inserted
anywhere an

if (strfmt == "foo")

;-)
-Arthur
[Disclaimer: THIS WHOLE THREAD IS A JOKE. THIS IS INTENTIONALLY
BAD CODE. WE KNOW IT DOES NOT WORK. :) ]
Nov 14 '05 #21

P: n/a
Nils Petter Vaskinn wrote:
On Tue, 13 Jan 2004 08:16:29 -0600, Randy Howard wrote:

.... snip ...

Did you miss the part where this code is INTENTIONALLY bad?


Well at least he spotted the error when he thought it was serious.
But the other equally sinister error which he missed (as did I at
first) is the failure to close the comment (it'll stand out in a
syntax highlighting editor, but gcc remains quiet).

Since logical errors count too I guess we could improve thee code
more by changing it to:

for (z = 10; z > 1; z--); /* Adds up some positive numbers
x += z; from 1 to 10 */\


My original criterion was that "gcc worst.c" accepts and links
without any protest.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #22

P: n/a
On Tue, 13 Jan 2004 11:28:20 GMT, CBFalconer <cb********@yahoo.com>
wrote in comp.lang.c:
Jack Klein wrote:
Jack Klein <ja*******@spamcop.net> wrote in comp.lang.c:
<jw******@cs.Helsinki.FI> wrote in comp.lang.c:
> On Mon, 12 Jan 2004, CBFalconer wrote:
> ... snip ... > > unsigned int z;
> >
> > while (!feof()) {
>
> While what? Always prefer an explicit comparision.

This is an explicit comparison. It is an explicit comparison of
the int value returned by feof() with 0, the result then negated.


...that is, assuming it returns a value since it invokes undefined
behavior by omitting the required FILE * argument.


You forget the objective is to make errors without having the
compiler complain. With no #include and no feof() prototype there
is no required argument and no complaint.

I specified the compiler and commands to use. I couldn't use void
main without triggering something elsewhere. There is actually
some value to this, because it alerts you to the sort of thing
that you won't get warnings for.


I never use a compiler that does not have issue warnings for calls to
unprototyped functions. And I never use such a compiler without the
option demanding that it do so.

The last compiler around that cannot be forced to do so dates from
1995, and is still used some in maintaining a legacy product.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #23

P: n/a
On Tue, 13 Jan 2004, Arthur J. O'Dwyer wrote:
ITYM
char* fmt = "%d, %l", c;
My mistake. ;-)
It would be better though if c was somehow used as if it were a
char* instead. Otherwise it just adds up to obfuscation.


I think you'd have trouble avoiding a compiler warning in that case.


Not really. Strings are usually handled through functions and we're
not including the important stuff to get complaints. (though in this
respect gcc is sometimes one of the "smart compilers" with its built in
checking for variadic functions)

> unsigned int z;
> while (!feof()) {
Surely you meant
while (!feof(stdin)) {
This will avoid the warnings from those so-called "smarter" compilers. :)


Dunno, it's one bug less if you ignore the misdefinition..


How so? My change merely replaces "undefined behavior upon calling
unprototyped function with wrong arguments" (which Chuck already had
elsewhere) with "undefined behavior upon passing NULL to feof()". Plus,
my bug is much subtler.


Ok. Just that the bug's on another line, here we just see the results;)

Doesn't that remove the bug, though? scanf("%d%s", z, &c) will
most likely try to store a string in the memory pointed to by &c
(invoking undefined behavior on buffer overrun); but the bug I was
trying to introduce there was that

scanf("%d", &foo);
gets(bar);

will store a number in 'foo', and then, assuming the user has pressed
'Return' to end that line of input, will proceed to read and discard
a single newline.
Ouch. I completely unrealized the intent there..

OTOH, the gets() doesn't actually have a bug then;
it will store only a single '\0', won't it? So maybe keep that gets(),
but introduce the

scanf("%d", &foo);
fgets(&c, sizeof &c, stdin);

bug(s) elsewhere in the code. [Bugs include lack of prototype for
fgets, causing undefined behavior when passing literal 0 as third
argument; mis#defined 'stdin' that causes the literal 0 in the first
place; passing NULL to fgets in the first place; buffer overflow;
abuse of the 'sizeof' operator; lack of error-checking on scanf;
and the above-mentioned mishandling of possible newline characters
in the input.]
You're approaching the bubble sort:

sizeof abuse, off by 2 error had it worked, unsigned gotcha,
z vs zz, extra ;, dangerous comparision, sequence point problem on
swap, zeroing data when &__a==&__b, invasion of implementation
namespace, possible trap when performing binary stuff on chars
and modification of a string literal.

while (feof()==EOF) {

I think the use of == for != is too blatant a mistake. But it
occurs to me that we haven't misused De Morgan's Rule yet; we need
something along the lines of


Nah. It just shows why you shouldn't write bad code in the first place.
Mistakes invite more mistakes. It was a genuine;)

while (feof()!=EOF || c=(int)getchar() != EOF) {
Subtle.. I don't like the doublecheck for eof though. Checking first
for eof and then for errors makes it look better thought out.

[I like my cast better than yours. Yours is only designed to
placate the compiler, AFAICT; mine has the "good" intention of
making sure the result of getchar() is wide enough to hold 'EOF'
before assignment to c. ;-) ]
So it's
"hideous practice that lets you shoot your own foot quietly"
against
"terrible misunderstanding of how the language works" ;)

Finally, it occurs to me that we haven't abused 'goto' yet, nor
attempted to 'switch' on some inappropriate type. Nor even inserted
anywhere an
if (strfmt == "foo")
;-)


I like !strcmp(strfmt, "foo")==0 too (for having actually seen it), but
maybe it's too obvious..

Nov 14 '05 #24

P: n/a
Dan Pop wrote:

In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.


Wrong compilation command. You're asking gcc to treat worst.c as a
GNU C program, NOT as a C program. You really need -ansi -pedantic
if you want to be sure that your code doesn't contain errors that a
C compiler MUST diagnose. Trivial example:


Hey look - I made up this game, so we'll play by MY rules :-) If
you don't do so I'll take my ball away and go home. ;-[

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #25

P: n/a
Jack Klein wrote:
CBFalconer <cb********@yahoo.com> wrote in comp.lang.c:

.... snip ...

I specified the compiler and commands to use. I couldn't use void
main without triggering something elsewhere. There is actually
some value to this, because it alerts you to the sort of thing
that you won't get warnings for.


I never use a compiler that does not have issue warnings for calls to
unprototyped functions. And I never use such a compiler without the
option demanding that it do so.


In reality I had to go around my normal aliases to avoid using
reasonable flags. But with them I wouldn't have been able to
easily create worst.c :-)

My normal configuration results in:
c:\c\junk>gcc worst.c
worst.c:16: warning: return type defaults to `int'
worst.c: In function `main':
worst.c:19: warning: initialization discards qualifiers from
pointer target type
worst.c:22: warning: implicit declaration of function `feof'
worst.c:23: warning: implicit declaration of function `getchar'
worst.c:26: warning: implicit declaration of function `gets'
worst.c:27: warning: implicit declaration of function `printf'
worst.c:28: warning: implicit declaration of function `fflush'
worst.c:29: warning: implicit declaration of function `malloc'
worst.c:30: warning: implicit declaration of function `realloc'
worst.c:32: warning: comparison of unsigned expression >= 0 is
always true
worst.c:17: warning: `x' might be used uninitialized in this
function

No fun at all :-[

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #26

P: n/a
On Tue, 13 Jan 2004 10:49:15 -0500, Arthur J. O'Dwyer wrote:
This change removes one of the bugs that was already present -- the
infinite loop on the value of z (which by definition is always >= 0).
Of course, my changes removed the infinite loop, too, by returning
from main inside the loop -- but still I think the comparison of an
unsigned value against 0 is a big enough bug that it should remain
intact.
We should have (apparently) nested loops then?
Oh, and what's the deal with the extra backslash at the end of the
line? Is that a newsreader artifact, or a potential bug I'm just not
seeing?


It's the result of a bug in my internal typing routines.

--
NPV

"the large print giveth, and the small print taketh away"
Tom Waits - Step right up

Nov 14 '05 #27

P: n/a
CBFalconer wrote:
Dan Pop wrote:
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:

Presented without further comment for "improvement"

/* ---------- worst.c -----------*/

/* The objective here is to include as many C errors as
possible, without triggering the compiler into objecting.
I have tried to get an error into each line. Logical
foulups count. The test compiler is gcc 3.2.1, executed
with "gcc worst.c", i.e. with absolutely no extra warning
enabled, and linking successfully.


Wrong compilation command. You're asking gcc to treat worst.c as a
GNU C program, NOT as a C program. You really need -ansi -pedantic
if you want to be sure that your code doesn't contain errors that a
C compiler MUST diagnose. Trivial example:

Hey look - I made up this game, so we'll play by MY rules :-) If
you don't do so I'll take my ball away and go home. ;-]


Pop's got a point, as usual. :)

If you don't pass any arguments to gcc, it compiles a C-like language
called GNU C. If you pass the correct arguments, it compiles Standard C.
As this is clc, we want to discuss Standard C as opposed to GNU C.

You could take your ball to a gcc-specific froup and play it by your
rules there, but it really isn't on-topic here due to some oddnesses of
how gcc behaves by default.

For example:

int foo(int arg)
{
int bar(int gry)
{
int zee = 23;

return gry * zee;
}

return bar(arg);
}

is a perfectly correct GNU C program, and it behaves such that bar() is
only visible within foo(). bar() is a local function, something that
does not exist in Standard C. I have no idea why the gcc people decided
to do that, but so far the Standards committee hasn't seen fit to
canonize the behavior. ;)

--
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.
Nov 14 '05 #28

P: n/a
August Derleth wrote:
CBFalconer wrote:
.... snip ...
Hey look - I made up this game, so we'll play by MY rules :-) If
you don't do so I'll take my ball away and go home. ;-]


Pop's got a point, as usual. :)

If you don't pass any arguments to gcc, it compiles a C-like language
called GNU C. If you pass the correct arguments, it compiles Standard
C. As this is clc, we want to discuss Standard C as opposed to GNU C.

You could take your ball to a gcc-specific froup and play it by your
rules there, but it really isn't on-topic here due to some oddnesses
of how gcc behaves by default.


Yabbut. Default gcc still compiles standard C, it just doesn't
criticize as much. If I had specified "no warnings on any
compiler with any settings" the task would be virtually
impossible. So for this game I consider Pops point ponderously
pedantic for the populace. :-)

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #29

P: n/a
Dan Pop wrote:
CBFalconer <cb********@yahoo.com> writes:
Yabbut. Default gcc still compiles standard C,


Let's see:

fangorn:~/tmp 15> cat test.c
int main()
{
int asm = 0;
return asm;
}

Looks like a standard C program to me, unless I'm missing something...

fangorn:~/tmp 16> gcc test.c
test.c: In function `main':
test.c:3: parse error before `asm'
fangorn:~/tmp 17> gcc -ansi test.c
fangorn:~/tmp 18>
it just doesn't
criticize as much. If I had specified "no warnings on any
compiler with any settings" the task would be virtually
impossible. So for this game I consider Pops point ponderously
pedantic for the populace. :-)


As usual, you're in dire need of a clue. If you want gcc to compile
correct standard C code as such, you NEED -ansi, period. If you want
gcc to behave as a conforming standard C compiler, you need -pedantic,
too, otherwise you won't get certain *mandatory* diagnostics.

One doesn't have to be a genius to realise that a game that doesn't
involve a conforming C compiler is pointless in the context of this
newsgroup.


This time you are completely right about gcc vs standard C.
Thanks for pointing it out in your normal diplomatic manner.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #30

This discussion thread is closed

Replies have been disabled for this discussion.