Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem 77: Greedy Gift Givers

5 views
Skip to first unread message

Bert

unread,
Jul 5, 2008, 8:31:31 PM7/5/08
to
Problem is documented at http://ace.delos.com/usacoprob2?a=deAhyErCKsK&S=gift1

Why doesn't this work?

/*
ID: albert.4
LANG: C
TASK: gift1
*/

#include <stdio.h>

#define MAXNAMELEN 14

main()
{
struct friend {
int money, ngifts; /* no. gifts */

char name[MAXNAMELEN];
};

int NP; /* no. people */

FILE* in = fopen("gift1.in" , "r");
FILE* out = fopen("gift1.out", "w");

fscanf(in, "%d", &NP);

struct friend f[NP];

int i = 0;

for (; i < NP; i++)
{
fscanf(in, "%s", f[i].name);
}

/* Until input tells us how much each friend has (later in this
prog), they're all broke */
i = 0;

for (; i < NP; i++)
{
f[i].money = 0;
}

char temp[MAXNAMELEN];

for (i = 0; i < NP; i++)
{
fscanf(in, "%s", temp);

if (f[i].name == temp)
{
int init; /* initial amount of money */

fscanf(in, "%d %d", init, f[i].ngifts);

f[i].money = init * -1; /* init is given to people */
f[i].money += init % f[i].ngifts;

int amteachpersongets = init / f[i].ngifts;

int j = 0;

char temp2[MAXNAMELEN];

for (; j < f[i].ngifts; j++)
{
fscanf(in, "%s", temp2);

int k = 0;

for (; k < NP; k++)
{
if (f[k].name == temp2)
{
f[k].money += amteachpersongets;
break;
}
}
}
}
}

for (i = 0; i < NP; i++)
{
fprintf(out, "%s %d\n", f[i].name, f[i].money);
}

exit(0);
}

Walter Roberson

unread,
Jul 5, 2008, 9:07:24 PM7/5/08
to
In article <b46a1e5a-b903-4ed5...@25g2000hsx.googlegroups.com>,

>Why doesn't this work?

>main()
>{

That line tells us that you are using a C89 compiler. A C99 compiler
would not have compiled that line because C99 does not the recognize
implicit int return type. Every C99 function must define -some- return
type, even if that return type is given as 'void' (which would
not be a good idea for the 'main' routine.)

> int NP; /* no. people */

> fscanf(in, "%d", &NP);

> struct friend f[NP];

But those lines tell us that you are using C99. C89 array lengths
must be defined at compile time. C99 allows variable length arrays
(VLA) in some circumstances.

You need to pick a compiler standard and stick with it.
If you mix-and-match features between compiler versions, we
cannot tell you what the program means.
--
"There are some ideas so wrong that only a very intelligent person
could believe in them." -- George Orwell

Bert

unread,
Jul 5, 2008, 9:24:41 PM7/5/08
to
On Jul 6, 11:07 am, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
> In article <b46a1e5a-b903-4ed5-b1f8-04b972c87...@25g2000hsx.googlegroups.com>,
>
> Bert <albert.xtheunkno...@gmail.com> wrote:
> >Problem is documented athttp://ace.delos.com/usacoprob2?a=deAhyErCKsK&S=gift1

> >Why doesn't this work?
> >main()
> >{
>
> That line tells us that you are using a C89 compiler. A C99 compiler
> would not have compiled that line because C99 does not the recognize
> implicit int return type. Every C99 function must define -some- return
> type, even if that return type is given as 'void' (which would
> not be a good idea for the 'main' routine.)
>
> > int NP; /* no. people */
> > fscanf(in, "%d", &NP);
> > struct friend f[NP];
>
> But those lines tell us that you are using C99. C89 array lengths
> must be defined at compile time. C99 allows variable length arrays
> (VLA) in some circumstances.
>
> You need to pick a compiler standard and stick with it.
> If you mix-and-match features between compiler versions, we
> cannot tell you what the program means.
> --
> "There are some ideas so wrong that only a very intelligent person
> could believe in them." -- George Orwell

OK - I've been referring to K&R 2nd Edition.
main()
becomes int main()

Can you now tell me what's wrong with the rest of the program?

Ben Bacarisse

unread,
Jul 5, 2008, 9:58:51 PM7/5/08
to
Bert <albert.xt...@gmail.com> writes:

> On Jul 6, 11:07 am, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)

<snip>


>> You need to pick a compiler standard and stick with it.
>> If you mix-and-match features between compiler versions, we
>> cannot tell you what the program means.
>> --
>> "There are some ideas so wrong that only a very intelligent person
>> could believe in them." -- George
>> Orwell

Best not to quote sig blocks.

> OK - I've been referring to K&R 2nd Edition.
> main()
> becomes int main()
>
> Can you now tell me what's wrong with the rest of the program?

The main things are (in no particular order):

(1) No error checking on things that can fail like fopen and fscanf.
(2) No decomposition into functions.
(3) Dangerous unbounded %s input formats.
(4) Misunderstanding how fscanf reads strings. Read FAQ 12.18a [1]
(4) Comparing strings by using == on pointers to them. FAQ 8.2.

[1] http://c-faq.com/

--
Ben.

CBFalconer

unread,
Jul 5, 2008, 11:07:28 PM7/5/08
to
Bert wrote:
>
> Problem is documented at http://ace.delos.com/usacoprob2?a=deAhyErCKsK&S=gift1
>
> Why doesn't this work?
... snip ...

Because it doesn't compile under either C90 or C99.

[1] c:\c\junk>cc junk.c
junk.c: In function `main':
junk.c:17: warning: ISO C89 forbids variable-size array `f'
junk.c:17: warning: ISO C89 forbids mixed declarations and code
junk.c:31: warning: ISO C89 forbids mixed declarations and code
junk.c:37: warning: format argument is not a pointer (arg 3)
junk.c:37: warning: format argument is not a pointer (arg 4)
junk.c:42: warning: ISO C89 forbids mixed declarations and code
junk.c:49: warning: ISO C89 forbids mixed declarations and code
junk.c:64: warning: implicit declaration of function `exit'
junk.c:35: warning: `init' might be used uninitialized in this
function

[1] c:\c\junk>gcc -std=c99 -pedantic -W -Wall -Wwrite-strings
junk.c
junk.c: In function `main':
junk.c:37: warning: format argument is not a pointer (arg 3)
junk.c:37: warning: format argument is not a pointer (arg 4)
junk.c:64: warning: implicit declaration of function `exit'

This is line 37 as I have compressed it:

> fscanf(in, "%d %d", init, f[i].ngifts);

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


Bert

unread,
Jul 6, 2008, 12:30:15 AM7/6/08
to
Why doesn't it do the problem correctly now?

#include <stdio.h>

#define MAXNAMELEN 14

char name[MAXNAMELEN];
};

fscanf(in, "%d", &NP);

struct friend f[NP];

int i = 0;

char temp[MAXNAMELEN];

if (strcmp(f[i].name, temp) == 0)


{
int init; /* initial amount of money */

fscanf(in, "%d %d", &init, &f[i].ngifts);

f[i].money = init * -1; /* init is given to people */

if (f[i].ngifts != 0)
{


f[i].money += init % f[i].ngifts;
}

int amteachpersongets = 0;

if (f[i].ngifts != 0)
{


int amteachpersongets = init / f[i].ngifts;
}

int j = 0;

char temp2[MAXNAMELEN];

for (; j < f[i].ngifts; j++)
{
fscanf(in, "%s", temp2);

int k = 0;

for (; k < NP; k++)
{

if (strcmp(f[k].name, temp2) == 0)

Barry Schwarz

unread,
Jul 6, 2008, 12:41:52 AM7/6/08
to
On Sat, 5 Jul 2008 17:31:31 -0700 (PDT), Bert
<albert.xt...@gmail.com> wrote:

>Problem is documented at http://ace.delos.com/usacoprob2?a=deAhyErCKsK&S=gift1
>
>Why doesn't this work?

Would you care to describe "doesn't work" so we have a fighting chance
to help.

>
>/*
>ID: albert.4
>LANG: C
>TASK: gift1
>*/
>
>#include <stdio.h>
>
>#define MAXNAMELEN 14
>
>main()
>{
> struct friend {
> int money, ngifts; /* no. gifts */
>
> char name[MAXNAMELEN];
> };
>
> int NP; /* no. people */
>
> FILE* in = fopen("gift1.in" , "r");
> FILE* out = fopen("gift1.out", "w");
>
> fscanf(in, "%d", &NP);
>
> struct friend f[NP];

So your compiler has extensions that allow variable length arrays and
definitions to follow executable statements. Many of us don't which
limits the number of people who can help you.

>
> int i = 0;
>
> for (; i < NP; i++)
> {
> fscanf(in, "%s", f[i].name);

If you gave us a sample of your input it would also help.

> }
>
> /* Until input tells us how much each friend has (later in this
>prog), they're all broke */
> i = 0;
>
> for (; i < NP; i++)
> {
> f[i].money = 0;

Is there some reason you chose not to do this in the previous loop?

> }
>
> char temp[MAXNAMELEN];
>
> for (i = 0; i < NP; i++)
> {
> fscanf(in, "%s", temp);

Don't you think this should be in front of the loop?

>
> if (f[i].name == temp)

This is guaranteed to always be false. If you want to compare
strings, you need to use strcmp et al. Read the faq (www.c-faq.com),
section 8.2. Then read the rest of the faq also.

> {
> int init; /* initial amount of money */
>
> fscanf(in, "%d %d", init, f[i].ngifts);
>
> f[i].money = init * -1; /* init is given to people */

Is there some reason -init does not provide the value you want?

> f[i].money += init % f[i].ngifts;

What is this quantity supposed to represent?

>
> int amteachpersongets = init / f[i].ngifts;
>
> int j = 0;
>
> char temp2[MAXNAMELEN];
>
> for (; j < f[i].ngifts; j++)
> {
> fscanf(in, "%s", temp2);
>
> int k = 0;
>
> for (; k < NP; k++)
> {
> if (f[k].name == temp2)
> {
> f[k].money += amteachpersongets;
> break;
> }
> }
> }
> }
> }
>
> for (i = 0; i < NP; i++)
> {
> fprintf(out, "%s %d\n", f[i].name, f[i].money);
> }
>
> exit(0);
>}


Remove del for email

santosh

unread,
Jul 6, 2008, 3:08:10 AM7/6/08
to
Bert wrote:

Do you realise that the link leads to a page that asks for
authentication?

<snip>

CBFalconer

unread,
Jul 6, 2008, 5:41:47 AM7/6/08
to
Barry Schwarz wrote:

> Bert <albert.xt...@gmail.com> wrote:
>
>> Why doesn't this work?
>
> Would you care to describe "doesn't work" so we have a fighting chance
> to help.
>
.... snip ...

>>
>> #include <stdio.h>
>>
>> #define MAXNAMELEN 14
>>
>> main()
>> {
>> struct friend {
>> int money, ngifts; /* no. gifts */
>> char name[MAXNAMELEN];
>> };
>>
>> int NP; /* no. people */
>>
>> FILE* in = fopen("gift1.in" , "r");
>> FILE* out = fopen("gift1.out", "w");
>>
>> fscanf(in, "%d", &NP);
>> struct friend f[NP];
>
> So your compiler has extensions that allow variable length arrays and
> definitions to follow executable statements. Many of us don't which
> limits the number of people who can help you.

Not to mention the use of undefined functions (exit) and implicit
int (main).

Richard Heathfield

unread,
Jul 6, 2008, 8:20:08 AM7/6/08
to
CBFalconer said:

> Barry Schwarz wrote:
>> Bert <albert.xt...@gmail.com> wrote:
>>
>>> Why doesn't this work?
>>
>> Would you care to describe "doesn't work" so we have a fighting chance
>> to help.
>>
> .... snip ...
>>>
>>> #include <stdio.h>
>>>

<snip>


>
> Not to mention the use of undefined functions (exit) and implicit
> int (main).

ITYM "undeclared functions". Either the presence of a standard C library
function in the library supplied with the implementation counts as a
definition or it doesn't. If it does, then exit() is defined. And if it
doesn't, the mere addition of a declaration (via #include <stdlib.h>) will
not provide a definition.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Willem

unread,
Jul 6, 2008, 8:51:49 AM7/6/08
to
Richard Heathfield wrote:
) ITYM "undeclared functions". Either the presence of a standard C library
) function in the library supplied with the implementation counts as a
) definition or it doesn't. If it does, then exit() is defined. And if it
) doesn't, the mere addition of a declaration (via #include <stdlib.h>) will
) not provide a definition.

Is exit() required to be a library function by the standard ?
Can't it be a macro ? For example:

#define exit(x) _exitprocess((x) == EXIT_SUCCESS ? 1 : 0)

(On systems where a process returns 0 to the shell for failure).


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

santosh

unread,
Jul 6, 2008, 9:07:12 AM7/6/08
to
Willem wrote:

> Richard Heathfield wrote:
> ) ITYM "undeclared functions". Either the presence of a standard C
> library ) function in the library supplied with the implementation
> counts as a ) definition or it doesn't. If it does, then exit() is
> defined. And if it ) doesn't, the mere addition of a declaration (via
> #include <stdlib.h>) will ) not provide a definition.
>
> Is exit() required to be a library function by the standard ?
> Can't it be a macro ? For example:
>
> #define exit(x) _exitprocess((x) == EXIT_SUCCESS ? 1 : 0)
>
> (On systems where a process returns 0 to the shell for failure).

As far as I can see, exit could be implemented as a macro too, though a
function must also be provided.

CBFalconer

unread,
Jul 6, 2008, 10:24:58 AM7/6/08
to
santosh wrote:
> Willem wrote:
>
... snip ...

>
>> Is exit() required to be a library function by the standard ?
>> Can't it be a macro ? For example:
>>
>> #define exit(x) _exitprocess((x) == EXIT_SUCCESS ? 1 : 0)
>>
>> (On systems where a process returns 0 to the shell for failure).
>
> As far as I can see, exit could be implemented as a macro too,
> though a function must also be provided.

If it is a macro, that macro is defined by #include <stdlib.h>.
However, since it is a non-returning function, it appears awkward
to provide a macro for it.

Keith Thompson

unread,
Jul 6, 2008, 5:34:28 PM7/6/08
to
Willem <wil...@stack.nl> writes:
> Richard Heathfield wrote:
> ) ITYM "undeclared functions". Either the presence of a standard C library
> ) function in the library supplied with the implementation counts as a
> ) definition or it doesn't. If it does, then exit() is defined. And if it
> ) doesn't, the mere addition of a declaration (via #include <stdlib.h>) will
> ) not provide a definition.
>
> Is exit() required to be a library function by the standard ?
> Can't it be a macro ? For example:
[...]

Like any other library function, it must be provided as a function.
The implementation may optionally implement it as a macro as well.

In particular, assuming you have a "#include <stdlib.h>", this:

(exit)(0);

or this:

#undef exit
exit(0);

must bypass any macro definition and call the actual function.
Similarly, you can assign the address of the exit function to a
pointer object.

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

Keith Thompson

unread,
Jul 6, 2008, 5:36:14 PM7/6/08
to
CBFalconer <cbfal...@yahoo.com> writes:
> santosh wrote:
>> Willem wrote:
> ... snip ...
>>
>>> Is exit() required to be a library function by the standard ?
>>> Can't it be a macro ? For example:
>>>
>>> #define exit(x) _exitprocess((x) == EXIT_SUCCESS ? 1 : 0)
>>>
>>> (On systems where a process returns 0 to the shell for failure).
>>
>> As far as I can see, exit could be implemented as a macro too,
>> though a function must also be provided.
>
> If it is a macro, that macro is defined by #include <stdlib.h>.
> However, since it is a non-returning function, it appears awkward
> to provide a macro for it.

I see nothing awkward about it. Willem even provided a plausible
example.

Except that I'd put parentheses around the whole definition:

#define exit(x) (_exitprocess((x) == EXIT_SUCCESS ? 1 : 0))

It's easier to add the parentheses than to figure out whether they're
really necessary.

Peter Nilsson

unread,
Jul 6, 2008, 6:38:03 PM7/6/08
to
Keith Thompson wrote:
> ...
> Like any other library function, it must be provided as a function.

Well... it's unspecified whether setjmp is an identifier declared
with external linkage, which gives it scope to be a library function
that needn't be provided as a function! :-)

--
Peter

CBFalconer

unread,
Jul 6, 2008, 9:49:19 PM7/6/08
to
Keith Thompson wrote:
> CBFalconer <cbfal...@yahoo.com> writes:
>> santosh wrote:
>>> Willem wrote:
>> ... snip ...
>>>
>>>> Is exit() required to be a library function by the standard ?
>>>> Can't it be a macro ? For example:
>>>>
>>>> #define exit(x) _exitprocess((x) == EXIT_SUCCESS ? 1 : 0)
>>>>
>>>> (On systems where a process returns 0 to the shell for failure).
>>>
>>> As far as I can see, exit could be implemented as a macro too,
>>> though a function must also be provided.
>>
>> If it is a macro, that macro is defined by #include <stdlib.h>.
>> However, since it is a non-returning function, it appears awkward
>> to provide a macro for it.
>
> I see nothing awkward about it. Willem even provided a plausible
> example.

Since the operation has to go somewhere and do something, it has to
transfer control. There must be code to which to transfer control
to. Since the code must exist and must be used, any macro is a
useless exercize. At least as I see it.

Keith Thompson

unread,
Jul 7, 2008, 12:35:52 AM7/7/08
to
CBFalconer <cbfal...@yahoo.com> writes:
> Keith Thompson wrote:
>> CBFalconer <cbfal...@yahoo.com> writes:
>>> santosh wrote:
>>>> Willem wrote:
>>> ... snip ...
>>>>
>>>>> Is exit() required to be a library function by the standard ?
>>>>> Can't it be a macro ? For example:
>>>>>
>>>>> #define exit(x) _exitprocess((x) == EXIT_SUCCESS ? 1 : 0)
>>>>>
>>>>> (On systems where a process returns 0 to the shell for failure).
>>>>
>>>> As far as I can see, exit could be implemented as a macro too,
>>>> though a function must also be provided.
>>>
>>> If it is a macro, that macro is defined by #include <stdlib.h>.
>>> However, since it is a non-returning function, it appears awkward
>>> to provide a macro for it.
>>
>> I see nothing awkward about it. Willem even provided a plausible
>> example.
>
> Since the operation has to go somewhere and do something, it has to
> transfer control. There must be code to which to transfer control
> to. Since the code must exist and must be used, any macro is a
> useless exercize. At least as I see it.

Read Willem's example again. The transfer of control is performed by
the _exitprocess() function. The macro serves to perform a simple
transformation on the argument.

Keith Thompson

unread,
Jul 7, 2008, 12:38:41 AM7/7/08
to

Well, the standard refers to it as "the setjmp macro", even though it
apparently doesn't require it to be a macro.

In any case, setjmp would simply be the exception that proves the
rule, if exceptions proved rules, which of course they don't, so I
was, er, um, wrong.

Bert

unread,
Jul 7, 2008, 12:59:23 AM7/7/08
to
Sorry adults

Greedy Gift Givers

A group of NP (2 ≤ NP ≤ 10) uniquely named friends has decided to
exchange gifts of money. Each of these friends might or might not give
some money to any or all of the other friends. Likewise, each friend
might or might not receive money from any or all of the other friends.
Your goal in this problem is to deduce how much more money each person
gives than they receive.

The rules for gift-giving are potentially different than you might
expect. Each person sets aside a certain amount of money to give and
divides this money evenly among all those to whom he or she is giving
a gift. No fractional money is available, so dividing 3 among 2
friends would be 1 each for the friends with 1 left over -- that 1
left over stays in the giver's "account".

In any group of friends, some people are more giving than others (or
at least may have more acquaintances) and some people have more money
than others.

Given a group of friends, no one of whom has a name longer than 14
characters, the money each person in the group spends on gifts, and a
(sub)list of friends to whom each person gives gifts, determine how
much more (or less) each person in the group gives than they receive.
IMPORTANT NOTE

The grader machine is a Linux machine that uses standard Unix
conventions: end of line is a single character often known as '\n'.
This differs from Windows, which ends lines with two charcters, '\n'
and '\r'. Do not let your program get trapped by this!
PROGRAM NAME: gift1
INPUT FORMAT
Line 1: The single integer, NP
Lines 2..NP+1: Each line contains the name of a group member
Lines NP+2..end: NP groups of lines organized like this:
The first line in the group tells the person's name who will be giving
gifts.
The second line in the group contains two numbers: The initial amount
of money (in the range 0..2000) to be divided up into gifts by the
giver and then the number of people to whom the giver will give gifts,
NGi (0 ≤ NGi ≤ NP-1).
If NGi is nonzero, each of the next NGi lines lists the the name of a
recipient of a gift.

SAMPLE INPUT (file gift1.in)

5
dave
laura
owen
vick
amr
dave
200 3
laura
owen
vick
owen
500 1
dave
amr
150 2
vick
owen
laura
0 2
amr
vick
vick
0 0

OUTPUT FORMAT

The output is NP lines, each with the name of a person followed by a
single blank followed by the net gain or loss (final_money_value -
initial_money_value) for that person. The names should be printed in
the same order they appear on line 2 of the input.

All gifts are integers. Each person gives the same integer amount of
money to each friend to whom any money is given, and gives as much as
possible that meets this constraint. Any money not given is kept by
the giver.
SAMPLE OUTPUT (file gift1.out)

dave 302
laura 66
owen -359
vick 141
amr -150


Submission file Name:
USACO Gateway | Comment or Question

Willem

unread,
Jul 7, 2008, 4:37:51 AM7/7/08
to
Bert wrote:
) Why doesn't it do the problem correctly now?

What is the incorrect output then, and what should the correct output be ?

Nick Keighley

unread,
Jul 7, 2008, 4:51:30 AM7/7/08
to
On 6 Jul, 02:07, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:

> You need to pick a compiler standard and stick with it.
> If you mix-and-match features between compiler versions, we
> cannot tell you what the program means.

well *you* might not be able to...

The semantice of C89 and C90 arn't *that*
different
--
Nick Keighley

Keith Thompson

unread,
Jul 7, 2008, 4:55:21 AM7/7/08
to

The semantics of C89 and C90 are identical. I presume you meant C90
vs. C99.

vipp...@gmail.com

unread,
Jul 8, 2008, 3:44:42 AM7/8/08
to
On Jul 6, 6:07 am, CBFalconer <cbfalco...@yahoo.com> wrote:
> Bert wrote:
>
> > Problem is documented at http://ace.delos.com/usacoprob2?a=deAhyErCKsK&S=gift1
>
> > Why doesn't this work?
>
> ... snip ...
>
> Because it doesn't compile under either C90 or C99.
>
> [1] c:\c\junk>cc junk.c
> junk.c: In function `main':
> junk.c:17: warning: ISO C89 forbids variable-size array `f'
<snip more warnings>

Note that 'cc' in your particular example is not a C compiler invoked
in C89/C90 conformance mode.

CBFalconer

unread,
Jul 8, 2008, 4:19:18 AM7/8/08
to
vipp...@gmail.com wrote:

> CBFalconer <cbfalco...@yahoo.com> wrote:
>
... snip ...
>
>> Because it doesn't compile under either C90 or C99.
>>
>> [1] c:\c\junk>cc junk.c
>> junk.c: In function `main':
>> junk.c:17: warning: ISO C89 forbids variable-size array `f'
> <snip more warnings>
>
> Note that 'cc' in your particular example is not a C compiler
> invoked in C89/C90 conformance mode.

You don't know that. As a matter of fact it is, being simply gcc
called via an alias.

Keith Thompson

unread,
Jul 8, 2008, 11:46:27 AM7/8/08
to
CBFalconer <cbfal...@yahoo.com> writes:
> vipp...@gmail.com wrote:
>> CBFalconer <cbfalco...@yahoo.com> wrote:
>>
> ... snip ...
>>
>>> Because it doesn't compile under either C90 or C99.
>>>
>>> [1] c:\c\junk>cc junk.c
>>> junk.c: In function `main':
>>> junk.c:17: warning: ISO C89 forbids variable-size array `f'
>> <snip more warnings>
>>
>> Note that 'cc' in your particular example is not a C compiler
>> invoked in C89/C90 conformance mode.
>
> You don't know that. As a matter of fact it is, being simply gcc
> called via an alias.

Does that alias pass the extra arguments needed to invoke C90
conforming mode? If so, you might have said so.

The warning message was characteristic of gcc. On many systems, the
"cc" command is identical to the "gcc" command (typically
"/usr/bin/cc" is a symbolic link to "/usr/bin/gcc"). The DOS-style
prompt does indicate that something else is going on, but vippstar's
assumption was not an entirely unreasonable one.

CBFalconer

unread,
Jul 8, 2008, 5:27:55 PM7/8/08
to
Keith Thompson wrote:
> CBFalconer <cbfal...@yahoo.com> writes:
>> vipp...@gmail.com wrote:
>>> CBFalconer <cbfalco...@yahoo.com> wrote:
>>>
>> ... snip ...
>>>
>>>> Because it doesn't compile under either C90 or C99.
>>>>
>>>> [1] c:\c\junk>cc junk.c
>>>> junk.c: In function `main':
>>>> junk.c:17: warning: ISO C89 forbids variable-size array `f'
>>> <snip more warnings>
>>>
>>> Note that 'cc' in your particular example is not a C compiler
>>> invoked in C89/C90 conformance mode.
>>
>> You don't know that. As a matter of fact it is, being simply gcc
>> called via an alias.
>
> Does that alias pass the extra arguments needed to invoke C90
> conforming mode? If so, you might have said so.

However, the point of the message was to point out that the source
didn't compile under either C90 or C99, by displaying the two sets
of error messages. All the rest is needless.

vipp...@gmail.com

unread,
Jul 9, 2008, 4:11:42 AM7/9/08
to
On Jul 8, 11:19 am, CBFalconer <cbfalco...@yahoo.com> wrote:

> vipps...@gmail.com wrote:
> > CBFalconer <cbfalco...@yahoo.com> wrote:
>
> ... snip ...
>
> >> Because it doesn't compile under either C90 or C99.
>
> >> [1] c:\c\junk>cc junk.c
> >> junk.c: In function `main':
> >> junk.c:17: warning: ISO C89 forbids variable-size array `f'
> > <snip more warnings>
>
> > Note that 'cc' in your particular example is not a C compiler
> > invoked in C89/C90 conformance mode.
>
> You don't know that. As a matter of fact it is, being simply gcc
> called via an alias.
The code is not valid in C89/C90, there was a constraint violation,
but no error was diagnosed.
Maybe I'm wrong and it is not a constraint violation! gcc in C90 mode
only warns for this code:

int main(void) { int i = 10; char foo[i]; return 0; }

I would find out myself but I don't have the C90 standard. Can anyone
help?

Richard Heathfield

unread,
Jul 9, 2008, 4:26:05 AM7/9/08
to
vipp...@gmail.com said:

<snip>

> Maybe I'm wrong and it is not a constraint violation!

It is.

> gcc in C90 mode
> only warns for this code:
>
> int main(void) { int i = 10; char foo[i]; return 0; }

The code violates the constraint in 3.5.4.2 that "The expression that
specifies the size of an array shall be an integral constant expression
that has a value greater than zero" because i is not an integral constant
expression. (And no, making it const won't help.)

The gcc implementation, in issuing a diagnostic message, fulfils its
conformance obligations to you. Whether it calls the message a warning or
an error is irrelevant, as long as it issues the message.

santosh

unread,
Jul 9, 2008, 5:22:51 AM7/9/08
to
vipp...@gmail.com wrote:

> On Jul 8, 11:19 am, CBFalconer <cbfalco...@yahoo.com> wrote:
>> vipps...@gmail.com wrote:
>> > CBFalconer <cbfalco...@yahoo.com> wrote:
>>
>> ... snip ...
>>
>> >> Because it doesn't compile under either C90 or C99.
>>
>> >> [1] c:\c\junk>cc junk.c
>> >> junk.c: In function `main':
>> >> junk.c:17: warning: ISO C89 forbids variable-size array `f'
>> > <snip more warnings>
>>
>> > Note that 'cc' in your particular example is not a C compiler
>> > invoked in C89/C90 conformance mode.
>>
>> You don't know that. As a matter of fact it is, being simply gcc
>> called via an alias.
> The code is not valid in C89/C90, there was a constraint violation,
> but no error was diagnosed.

Maybe I'm wrong, but I believe that a constraint violation only requires
a diagnostic (commonly a warning). The further behaviour of the
translation is undefined by the standard and the implementation can do
anything including compiling the code anyway, refusing translation,
deleting all your files etc.

I believe that the only construct that must absolutely stop compilation
is an active #error directive. All syntax errors and constraint
violations require a diagnostic but translation need not necessarily
halt, though they commonly do so for syntax errors.

> Maybe I'm wrong and it is not a constraint violation! gcc in C90 mode
> only warns for this code:
>
> int main(void) { int i = 10; char foo[i]; return 0; }
>
> I would find out myself but I don't have the C90 standard. Can anyone
> help?

The clc Wiki has a draft of the old ANSI standard. Maybe that can help
you?

Richard Heathfield

unread,
Jul 9, 2008, 5:52:30 AM7/9/08
to
santosh said:

<snip>



> Maybe I'm wrong, but I believe that a constraint violation only requires
> a diagnostic (commonly a warning).

(Here I refer to C89.) The term used by the Standard is "diagnostic
message". If a program contains at least one constraint violation or at
least one syntax error, the translator must issue a diagnostic message.
The message "Your program contains at least one constraint violation or
syntax error" would be conforming, albeit rather unhelpful. Diagnostic
messages are implementation-defined, so they must be documented.

The Standard doesn't mention the word "warning" even once in normative
text. It does mention the phrase "error message" four times in normative
text (three of which are in relation to perror and one in relation to
strerror), but in each case it's talking about runtime behaviour, not what
happens during translation.

vipp...@gmail.com

unread,
Jul 9, 2008, 6:21:47 PM7/9/08
to
On Jul 9, 12:22 pm, santosh <santosh....@gmail.com> wrote:
> vipps...@gmail.com wrote:
<snip>

> > I would find out myself but I don't have the C90 standard. Can anyone
> > help?
>
> The clc Wiki has a draft of the old ANSI standard. Maybe that can help
> you?
Thanks! This will help a lot.

vipp...@gmail.com

unread,
Jul 9, 2008, 6:28:18 PM7/9/08
to
On Jul 9, 11:26 am, Richard Heathfield <r...@see.sig.invalid> wrote:

> vipps...@gmail.com said:
>
> <snip>
>
> > Maybe I'm wrong and it is not a constraint violation!
>
> It is.
>
> > gcc in C90 mode
> > only warns for this code:
>
> > int main(void) { int i = 10; char foo[i]; return 0; }
>
> The code violates the constraint in 3.5.4.2 that "The expression that
> specifies the size of an array shall be an integral constant expression
> that has a value greater than zero" because i is not an integral constant
> expression. (And no, making it const won't help.)
>
> The gcc implementation, in issuing a diagnostic message, fulfils its
> conformance obligations to you. Whether it calls the message a warning or
> an error is irrelevant, as long as it issues the message.
Great, thanks. I always thought there are "error messages" and
"warning messages", such as that the compiler has to print at least
one of the former if a constraint violation/syntax error happends, and
that the compiler is free to print any number of the latter.
I have a question though, if warning messages (ie warning: text) are
allowed by the standard to be printed for constraint violations, how
can the programmer differentiate between a successfully compiled
program and one which had a syntax error or a constraint violation?
This is purely academic, of course all compilers will attempt to have
meaningful error/warning messages such that the programmer will
_receive_ information from them instead of confusion.

Richard Heathfield

unread,
Jul 9, 2008, 7:02:55 PM7/9/08
to
vipp...@gmail.com said:

<snip>

> I have a question though, if warning messages (ie warning: text) are
> allowed by the standard to be printed for constraint violations,

The Standard requires the implementation to produce a diagnostic message if
the program contains any syntax errors or constraint violations. The
Standard does not require the implementation to give these diagnostic
messages a badge of "warning" or "error", but you can call them warning
messages if you like.

> how
> can the programmer differentiate between a successfully compiled
> program and one which had a syntax error or a constraint violation?

I'm afraid the answer is that a program for which the translator emits at
least one diagnostic message may (or may not) contain at least one syntax
error or constraint violation. That is - if the translator is a conforming
implementation and NO messages are produced, you know that the program
didn't contain any syntax errors or constraint violations. (It might still
contain mistakes of logic or instances of undefined behaviour, of course.)

> This is purely academic, of course all compilers will attempt to have
> meaningful error/warning messages such that the programmer will
> _receive_ information from them instead of confusion.

That was never the impression I got when I was first learning C. :-)

Bert

unread,
Jul 10, 2008, 2:09:07 AM7/10/08
to
Well, this compiles on the compiler somewhere else wherever I sent
this to. Could you guys please point out which parts could be improved
oh and I just realised you're all professionals...um...could you
please INDICATE the points where I need to do all the error checking
like the try..catch kinda things for all kinds of exceptions (only C
doesn't have this cool stuff) like for adverse inputs? Thanks

/*
ID: albert.4
LANG: C
TASK: gift1
*/

#include <stdio.h>

#define MAXNAMELEN 20

main()
{
/*************************************************/
struct friend {
int money, ngifts;

char name[MAXNAMELEN];
};

int NP;

FILE* in = fopen("gift1.in" , "r");
FILE* out = fopen("gift1.out", "w");

fscanf(in, "%d", &NP);


struct friend f[NP];

int i = 0;

for (; i < NP; i++)
{
fscanf(in, "%s", f[i].name);
f[i].money = 0;
}
/*************************************************/

/*************************************************/
int m = 0;
for (; m < NP; m++)
{
struct friend* currf;
char temp[MAXNAMELEN];

fscanf(in, "%s", temp);

i = 0;
for (; i < NP; i++)
{
if ( strcmp(temp, f[i].name) == 0 )
{
currf = &f[i];
/* printf("Current friend%s\n", f[i].name); */
break;
}
}
/*************************************************/

/*************************************************/
int init;
fscanf(in, "%d %d", &init, &currf->ngifts);
currf->money += -1 * init;
if (currf->ngifts != 0)
{
currf->money += init % currf->ngifts;
}
/* printf("%d %d\n", init, currf->ngifts); */
/*************************************************/

char receivers[currf->ngifts][MAXNAMELEN];
int j = 0;
int l;
for (; j < currf->ngifts; j++)
{
fscanf(in, "%s", receivers[j]);
/* printf("%s\n", receivers[j]); */

l = 0;
for (; l < NP; l++)
{
if ( strcmp(receivers[j], f[l].name) == 0 )
{
/* printf("%s\n", f[l].name); */
f[l].money += init / currf->ngifts;
/* printf("%d\n", f[l].money); */
}
}
}
}

/*************************************************/
for (i = 0; i < NP; i++)
{
fprintf(out, "%s %d\n", f[i].name, f[i].money);
}
/************************************************/

exit(0);
}

santosh

unread,
Jul 10, 2008, 2:17:48 AM7/10/08
to
Bert wrote:

> Well, this compiles on the compiler somewhere else wherever I sent
> this to. Could you guys please point out which parts could be improved
> oh and I just realised you're all professionals...um...could you
> please INDICATE the points where I need to do all the error checking
> like the try..catch kinda things for all kinds of exceptions (only C
> doesn't have this cool stuff) like for adverse inputs? Thanks
>
> /*
> ID: albert.4
> LANG: C
> TASK: gift1
> */
>
> #include <stdio.h>

You need in addition stdlib.h and string.h.

<snip code>

Richard Heathfield

unread,
Jul 10, 2008, 2:30:38 AM7/10/08
to
Bert said:


> #include <stdio.h>

santosh has already pointed out that you're missing a couple of headers.

> #define MAXNAMELEN 20
>
> main()
> {
> /*************************************************/
> struct friend {
> int money, ngifts;
>
> char name[MAXNAMELEN];
> };
>
> int NP;

Minor problem.

>
> FILE* in = fopen("gift1.in" , "r");

Problem.

> FILE* out = fopen("gift1.out", "w");

Problem.

>
> fscanf(in, "%d", &NP);

Problem.

>
>
> struct friend f[NP];

Your compiler *must* either diagnose the lack of an explicit return type
for main (C99) or the mixture of code and declarations (C90), so we know
you're posting code that doesn't compile cleanly. Why bother? First, fix
the stuff that can be diagnosed automatically.

> int i = 0;
>
> for (; i < NP; i++)
> {
> fscanf(in, "%s", f[i].name);

Two problems.

That'll do to be going on with. When you've got a clean compile and are at
least curious about the problems I've outlined above...

<snip>

santosh

unread,
Jul 10, 2008, 2:56:44 AM7/10/08
to
Bert wrote:

> Well, this compiles on the compiler somewhere else wherever I sent
> this to. Could you guys please point out which parts could be improved
> oh and I just realised you're all professionals...um...could you
> please INDICATE the points where I need to do all the error checking
> like the try..catch kinda things for all kinds of exceptions (only C
> doesn't have this cool stuff) like for adverse inputs? Thanks

C does not have support for exceptions so you need to check that each
library function you call has in fact succeeded. Each function has it's
own way of documenting failures; some return null pointers, others EOF,
still others return a count and so on. You should consult the
documentation for your Standard library and write in checks as
appropriate. A good on-line reference for the Standard library is
<http://www.dinkumware.com/manuals/>.

What you do when a function has failed will obviously be highly
dependant on the exact situation, but for small test programs (like
yours) you might want to print a useful message printing what went
wrong and where (function and source line number) and probably, exit.
Recovery strategies (even if they are possible) may be too advanced at
this point.

An example:

if (fscanf(file, "%d", &i) != 1) {
fprintf(stderr, "%s (%d): fscanf() failed.\n",
__FILE__, __LINE__);
exit(EXIT_FAILURE);
}

With C99 you can also use the predefined identifier __func__ to extract
the name of the current function (as a string).

For checking the internal consistency of the program you can use the
macro assert in assert.h. If the expression passed to assert evaluates
to zero (logically false), assert will print a message and abort the
program. You can define the macro NDEBUG *prior* to including assert.h
to turn off all assertions.

Many library functions also set the object 'errno' to some integer value
upon failure. To use this mechanism you need to include the header
errno.h and set errno to zero before the function in question is
called. Immediately after you need to check errno for the presence of
documented error values (like ERANGE, EDOM, EILSEQ and other
implementation defined values), and if so, take appropriate action. You
can translate the error codes in errno to implementation specific
messages using the strerror or perror.

In addition to all this C99 has added considerable diagnostic facilities
for floating point and maths functions; consult the Standard for
details.

Draft of C1x <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>

<snip>

Bert

unread,
Jul 10, 2008, 4:14:43 AM7/10/08
to
On Jul 10, 4:30 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
When you've got a clean compile and are at
> least curious about the problems I've outlined above...

You're wrong!!!
LMFAO
http://albert.xtheunknown0.googlepages.com/home

santosh

unread,
Jul 10, 2008, 4:26:35 AM7/10/08
to
Bert wrote:

> On Jul 10, 4:30 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> When you've got a clean compile and are at
>> least curious about the problems I've outlined above...
>
> You're wrong!!!
> LMFAO

*plonk*

<snip>

Richard Heathfield

unread,
Jul 10, 2008, 4:59:08 AM7/10/08
to
Bert said:

> On Jul 10, 4:30 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> When you've got a clean compile and are at
>> least curious about the problems I've outlined above...
>
> You're wrong!!!

Nope. Here's a favourite Chris Torek quote:

"Someone once told me it's illegal to carry the ball around
the court in basketball [i.e., to walk or run without bouncing
the ball on the ground -- `dribbling']. Well, I tried it
last night, and it worked fine. I did not get arrested.
Whoever told me that must be an idiot!"

> LMFAO
> http://albert.xtheunknown0.googlepages.com/home

If you're getting a clean compile, your compiler is non-conforming. A
compiler that conforms to C90 must at the very least diagnose the mixed
code and declarations, and a compiler that conforms to C99 must at the
very least diagnose the lack of an explicit return type for main. A
compiler that diagnoses neither fails to conform to either C90 or C99, and
therefore cannot reasonably claim to be a modern C compiler.

Bert

unread,
Jul 10, 2008, 5:23:30 AM7/10/08
to

Try telling that to the competition organisers and let us know how you
go. Doing the stuff I do that ain't that great makes it sorta more
similar to C# which is a lot more fun btw, though slower. Do you
wanna tell me what to do about the problems cos it ain't in k&r, I've
never had anyone say what you said to me.
Oh, and you should get used to some programming comps.

Richard Heathfield

unread,
Jul 10, 2008, 5:35:31 AM7/10/08
to
Bert said:

> On Jul 10, 6:59 pm, Richard Heathfield <r...@see.sig.invalid> wrote:

<snip>

>> If you're getting a clean compile, your compiler is non-conforming. A
>> compiler that conforms to C90 must at the very least diagnose the mixed
>> code and declarations, and a compiler that conforms to C99 must at the
>> very least diagnose the lack of an explicit return type for main. A
>> compiler that diagnoses neither fails to conform to either C90 or C99,
>> and therefore cannot reasonably claim to be a modern C compiler.
>>

> Try telling that to the competition organisers and let us know how you
> go.

What is your goal? To learn C, or to win a broken competition hosted by
people who don't understand the language? If it's the former, you should
start paying more attention to what you're told. If it's the latter, which
seems to be the case at the moment, I don't understand why you continue to
post in comp.lang.c.

Bert

unread,
Jul 10, 2008, 5:55:59 AM7/10/08
to

Well there's no other resource for help with these programming
competitions. Like there's ONE book on amazon.com that is specifically
for programming comps and I haven't got it yet, I don't know any
websites that help, I don't know people who've won programming comps,
I'm by myself, I'm apparently talking to a person who doesn't really
like me who won't tell me or even try suggest me to me where to go for
other help, like the comp has really completely broken my attention to
the 'standard' form of coding in C, but as a teen I'm really bored,
there's nothing else good to do in IT while I'm still in high school
other than to learn a million apps, print hello world onto a console,
so I've found it necessary to do programming comps. Like no one else
at school does it, it sounds pretty fun. Like if I had to fix all the
problems you mentioned I'd have to buy some c texts and find that 1%
of it is currently what I need, another 1% from an algorithm book for
use in programming comps, and I can't buy a dozen expensive texts just
to get so little of it just because I don't do this for a living (NOT
YET). Like programming in C at my level ain't what a normal teenager
does but I like it so that renders what I said moot. Like I don't live
next door to any of youse, I can't go on MSN to talk about this, I
can't email you pplz, I have to wait an hour for a response from
someone (mode value). Like you guys don't credit what I write and I
understand why you don't and you have reasons that are far superior to
mine but I'm now no longer a total noob to C programming, not
professional yet either and it's kinda hard being in between. Maybe
you can recommend to me what I should do now assuming I continue
practicing for the programming comps.

Richard Heathfield

unread,
Jul 10, 2008, 6:25:56 AM7/10/08
to
Bert said:

> On Jul 10, 7:35 pm, Richard Heathfield <r...@see.sig.invalid> wrote:

<snip>

>> What is your goal? To learn C, or to win a broken competition hosted by
>> people who don't understand the language? If it's the former, you should
>> start paying more attention to what you're told. If it's the latter,
>> which seems to be the case at the moment, I don't understand why you
>> continue to post in comp.lang.c.
>>

> Well there's no other resource for help with these programming
> competitions.

This newsgroup is a resource for discussing the C language.

<snip>

> I'm apparently talking to a person who doesn't really
> like me

If you mean me, you are mistaken in thinking that I don't like you,
although I will acknowledge that I'm a little concerned at your apparent
unwillingness to accept the help that is offered.

> who won't tell me or even try suggest me to me where to go for
> other help,

You *are* getting help here. You just don't seem to be able to recognise
the fact.

<snip>

> Like if I had to fix all the
> problems you mentioned I'd have to buy some c texts

Not really (although that wouldn't hurt you, if you bought good C
textbooks, which is harder than it sounds); you could make a great start
just by applying the fixes we tell you about, and learn why they matter -
before long, it becomes second nature.

> [...] I don't do this for a living (NOT YET).

If you want to program for a living, at some point you will need to learn
the difference between hack-n-slash coding and robust professional
programming.

> [...] Like you guys don't credit what I write

Give us a reason to credit it, by taking and applying the advice that we
offer.

<snip>

> Maybe
> you can recommend to me what I should do now assuming I continue
> practicing for the programming comps.

Yes, I can do that. I recommend that you start paying attention to what
we're saying, and applying those lessons to your code. Before long, you'll
find that you are writing better *and* faster C programs.

Keith Thompson

unread,
Jul 14, 2008, 4:23:34 PM7/14/08
to

Typically, compilers do distinguish between error messages and warning
messages. The distinction is that (a) warning messages typically
begin with the word "warning", and (b) a warning doesn't cause
compilation to fail, but an error does.

I've seen even more distinctions than that. For example, a "fatal
error" might cause the compiler to immediately stop processing the
input file, an ordinary "error" might set an internal flag that will
cause compilation to fail, but the compiler continues to attempt to
process the rest of the source file (in an attempt to diagnose more
errors), a "warning" indicates a probable problem but doesn't cause
the compilation to fail, and an "informational message" is something
the compiler thinks you should know that isn't necessarily a problem
(these are often disabled by default).

The standard makes no such distinctions. It requires a "diagnostic
message" for any translation unit containing a constraint violation or
syntax error. The definition of "diagnostic message" is left entirely
up to the implementation. Additional diagnostics may be issued for
things that are not constraint violations or syntax errors; the
implementation needn't distinguish these. Once a required diagnostic
message has been issued, the compiler may or may not successfully
translate the source file; if it does so, the behavior of the
resulting program is undefined.

A compiler must fail to compile a source file containing a #error
directive (if it's not skipped by #if or #ifdef); that's the only case
where such a failure is required. A compiler must successfully
compile a source file that doesn't contain a #error directive, a
constraint violation, a syntax error, or anything that exceeds some
capacity limit.

There's a whole lot of wiggle room in between.

Chris Torek

unread,
Jul 24, 2008, 5:39:45 AM7/24/08
to
In article <b5ednRW9fMTaU-jV...@bt.com>

Richard Heathfield <r...@see.sig.invalid> wrote:
>Here's a favourite Chris Torek quote:
>
>"Someone once told me it's illegal to carry the ball around
>the court in basketball [i.e., to walk or run without bouncing
>the ball on the ground -- `dribbling']. Well, I tried it
>last night, and it worked fine. I did not get arrested.
>Whoever told me that must be an idiot!"

Actually, that was my paraphrase of Steve Summit quoting yet another
person (Steve told me who but I have forgotten again).

It does illustrate, in an interesting way, what it means for code
to be "against the Standard". Code that violates various rules
may work just fine, as long as you do not get caught. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html

Richard Heathfield

unread,
Jul 24, 2008, 7:47:33 AM7/24/08
to
Chris Torek said:

> In article <b5ednRW9fMTaU-jV...@bt.com>
> Richard Heathfield <r...@see.sig.invalid> wrote:
>>Here's a favourite Chris Torek quote:
>>
>>"Someone once told me it's illegal to carry the ball around
>>the court in basketball [i.e., to walk or run without bouncing
>>the ball on the ground -- `dribbling']. Well, I tried it
>>last night, and it worked fine. I did not get arrested.
>>Whoever told me that must be an idiot!"
>
> Actually, that was my paraphrase of Steve Summit quoting yet another
> person (Steve told me who but I have forgotten again).

I think it may be way too late to correct this. Your "authorship" of the
above quote is firmly embedded in my mind. I'll do my best not to repeat
the misattribution, but I can make no guarantees!

> It does illustrate, in an interesting way, what it means for code
> to be "against the Standard". Code that violates various rules
> may work just fine, as long as you do not get caught. :-)

Yes. That's why we could play video RAM shenanigans in the 1980s and early
1990s. We didn't get caught until about 1995 or so.

Bert

unread,
Jul 26, 2008, 6:29:51 AM7/26/08
to
I've got a weak, but nonetheless interesting argument against writing
code 'professionally' in reference to checking inputs: The amount of
time you spend coding that will slowly accumulate over the 4 hour
period when the competition is on and you'd be wasting way too much
time checking against bad inputs. If you ever try one of these comps
try doing it 'professionally' and see how little or how much time it
takes to check bad inputs.

:)

santosh

unread,
Jul 26, 2008, 7:13:42 AM7/26/08
to
Bert wrote:

The organisers of the competition should specify whether they expect
full error checking or code that concentrates on solving the stated
problem. There is nothing wrong in writing code without error checking
provided it is understood that it merely for illustrative purposes. For
example Kernighan and Ritchie omit almost all error checking in the
code they present in K&R, and they carefully mention this in more than
one place in the book.

Ben Bacarisse

unread,
Jul 26, 2008, 7:33:28 AM7/26/08
to
Bert <albert.xt...@gmail.com> writes:

It depends of you do one or more. After the first example you posted,
I already had "int read_num(FILE *fp);" written so it took zero time
to check the input format for the second.

As for file opening, you have to write:

FILE *in = fopen("aflin.txt" , "r");
FILE *out = fopen("aflout.txt", "w");

so how long does it take to write:

if (in && out) {
}

after it? You don't need an error message and even if you always
develop competition code in a debugger it is quicker to see you have
got an open error (maybe you mistyped the name?) this way than by
asking to see "in" or "out".

For "quick and dirty" programs, C gives you an excellent way proceed
only if thing are OK:

if ((in = fopen("aflin.txt" , "r")) &&
(out = fopen("aflout.txt", "w")) &&
(size = read_num(in)) <= 30000 &&
(data = malloc(size * sizeof *data)) &&
...)

etc. You won't get good diagnostics, but you will save time if there
is some problem and is hardly any shorter that writing it without the
tests.

--
Ben.

0 new messages