From: Richard Heathfield on
In <hg4r6q$vr7$1(a)news.eternal-september.org>, Alf P. Steinbach wrote:

> * Richard Heathfield:
>> In <fopen-20091214031708(a)ram.dialup.fu-berlin.de>, Stefan Ram
>> wrote:
>>
<snip>

>> Seeing printto called twice made /me/ nervous! This is one of those
>> situations where you have to duplicate /something/ (I duplicated
>> the fp test, and you duplicated the print functionality, albeit
>> very wisely encapsulating it), and either choice can be shown to be
>> superior in some way to the other choice - but you only get to
>> choose one. That's one of the subtler skills of programming -
>> making the right choice among several valid but mutually exclusive
>> possibilities.

<snip>

> #include <stdio.h>
> #include <stdlib.h>
>
> int main( int argc, char **argv )
> {
> double const d = 3.1415926;
> float const f = 42.01F;
>
> FILE* const fp = (argc > 1? fopen( argv[1], "w" ) :
> stdout);
>
> if( fp == 0 )
> {
> return EXIT_FAILURE;

And your choice is to double the number of exits from the function.

None of these choices is wrong. In fact, all of them are right.
Choosing between right solutions and wrong solutions is easy,
assuming you know which is which. Choosing between right solutions is
harder, and will depend largely on style preferences.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
From: Alf P. Steinbach on
* Richard Heathfield:
> In <hg4r6q$vr7$1(a)news.eternal-september.org>, Alf P. Steinbach wrote:
>
>> * Richard Heathfield:
>>> In <fopen-20091214031708(a)ram.dialup.fu-berlin.de>, Stefan Ram
>>> wrote:
>>>
> <snip>
>
>>> Seeing printto called twice made /me/ nervous! This is one of those
>>> situations where you have to duplicate /something/ (I duplicated
>>> the fp test, and you duplicated the print functionality, albeit
>>> very wisely encapsulating it), and either choice can be shown to be
>>> superior in some way to the other choice - but you only get to
>>> choose one. That's one of the subtler skills of programming -
>>> making the right choice among several valid but mutually exclusive
>>> possibilities.
>
> <snip>
>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> int main( int argc, char **argv )
>> {
>> double const d = 3.1415926;
>> float const f = 42.01F;
>>
>> FILE* const fp = (argc > 1? fopen( argv[1], "w" ) :
>> stdout);
>>
>> if( fp == 0 )
>> {
>> return EXIT_FAILURE;
>
> And your choice is to double the number of exits from the function.

If you don't like the early exit you can just add an 'else'.


> None of these choices is wrong. In fact, all of them are right.
> Choosing between right solutions and wrong solutions is easy,
> assuming you know which is which. Choosing between right solutions is
> harder, and will depend largely on style preferences.

Mine is of course the only reasonable choice. He he. :-p


Cheers,

- Alf
From: Ian Collins on
Richard Heathfield wrote:
> In <fopen-20091214031708(a)ram.dialup.fu-berlin.de>, Stefan Ram wrote:
>
>> Richard Heathfield <rjh(a)see.sig.invalid> writes:
>>> if(fp != NULL)
>>> {
>>> fprintf(fp, "%f %f\n", d, f);
>>> }
>>>
>>> if(fp != NULL && fp != stdout)
>> Seing fp being tested twice made me nervous, so I rewrote it:
>>
>> #include <stdio.h>
>>
>> void printto( FILE * const fp )
>> { double const d = 3.1415926;
>> float const f = 42.01F;
>> fprintf( fp, "%f %f\n", d, f ); }
>>
>> int main( int argc, char * argv[] )
>> { if( argc > 1 )
>> { FILE * const fp = fopen( argv[ 1 ], "w" );
>> if( fp ){ printto( fp ); fclose( fp ); }}
>> else printto( stdout ); }
>
> Seeing printto called twice made /me/ nervous! This is one of those
> situations where you have to duplicate /something/ (I duplicated the
> fp test, and you duplicated the print functionality, albeit very
> wisely encapsulating it), and either choice can be shown to be
> superior in some way to the other choice - but you only get to choose
> one. That's one of the subtler skills of programming - making the
> right choice among several valid but mutually exclusive
> possibilities.

Don't duplicate:

#include <stdio.h>

int main(int argc, char **argv)
{
FILE *fp = stdout;
if(argc > 1)
{
fp = fopen(argv[1], "w");
}

if(fp != NULL)
{
double d = 3.1415926;
float f = 42.01F;

fprintf(fp, "%f %f\n", d, f);

if( fp != stdout)
{
fclose(fp);
}
}
return 0;
}

--
Ian Collins
From: Helge Kruse on
Am 14.12.2009 10:49, schrieb Richard Heathfield:
> In<hg4r6q$vr7$1(a)news.eternal-september.org>, Alf P. Steinbach wrote:
>
>> #include<stdio.h>
>> #include<stdlib.h>
>>
>> int main( int argc, char **argv )
>> {
>> double const d = 3.1415926;
>> float const f = 42.01F;
>>
>> FILE* const fp = (argc> 1? fopen( argv[1], "w" ) :
>> stdout);
>>
>> if( fp == 0 )
>> {
>> return EXIT_FAILURE;
>
> And your choice is to double the number of exits from the function.

There is no "right" choice of coding style. You should define the
requirements for your style and define it. But Alf's proposal has as
advantage points:

- The errors are checked as early as possible. After the check you read
only the code as it should work.

- The check for input parameter at /interface/ functions is a style that
makes software more reliable in contrast to spreaded checks.

- It's much easier to read than Stafan's approach. Such compressed style
may save some microseconds when the compiler reads it. But the compiler
is fairly inexpensive. The time spent by software developer is more
expensive. Make it easy for (the other) developers to read the code.

> None of these choices is wrong. In fact, all of them are right.

As they stand alone, you're right. It's a style decision. I think the
most important thing is to share the style with your co-workers.

Helge
From: Jerry Coffin on
In article <fopen-20091214031708(a)ram.dialup.fu-berlin.de>,
ram(a)zedat.fu-berlin.de says...
>
> Richard Heathfield <rjh(a)see.sig.invalid> writes:
> > if(fp != NULL)
> > {
> > fprintf(fp, "%f %f\n", d, f);
> > }
> >
> > if(fp != NULL && fp != stdout)
>
> Seing fp being tested twice made me nervous, so I rewrote it:
>
> #include <stdio.h>
>
> void printto( FILE * const fp )
> { double const d = 3.1415926;
> float const f = 42.01F;
> fprintf( fp, "%f %f\n", d, f ); }
>
> int main( int argc, char * argv[] )
> { if( argc > 1 )
> { FILE * const fp = fopen( argv[ 1 ], "w" );
> if( fp ){ printto( fp ); fclose( fp ); }}
> else printto( stdout ); }

Yet another possibility (skipping over 'printto()', which isn't very
interesting) would be:

int main(int argc, char **argv) {
FILE *fp=stdout;

if (argc > 1)
fp = fopen(argv[1], "w");
if (NULL == fp)
return EXIT_FAILURE;
printto(fp);
return 0;
}

--
Later,
Jerry.