Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: programi parsing question

Reply
Thread Tools

Re: programi parsing question

 
 
fjblurt@yahoo.com
Guest
Posts: n/a
 
      08-06-2008
Crossposting this to comp.lang.c because it's become relevant.

Our story so far, for c.l.c people:

There is a discussion about the stylistic advantages and disadvantages
of the following two snippets:

void foo (void) {
int fd;
if ((fd = open(...)) < 0) {
fail();
}
}

versus

void foo (void) {
int fd = open(...);
if (fd < 0) {
fail();
}
}

Phlip prefers the latter, and claims that the former gained popularity
because early versions of C did not guarantee the order in which
initializations occurred, or had other problems, and therefore
initializations in declarations were discouraged.

On Aug 5, 6:22 pm, Phlip <(E-Mail Removed)> wrote:
> K-mart Cashier wrote:
> > if((fd = open(_PATH_UTMP, O_RDONLY)) < 0)

>
> > is a common found in both "The C Programming Language" by K & R and
> > the FreeBSD source code.

>
> If they all just jumped off a cliff, would you?
>
> Seriously, the style is a legacy of days when C could not initialize reliably.


Do you have a specific example? K&R, first edition, doesn't seem to
address the issue of order specifically, but does say (appendix A,
section 8.6): "Automatic or register variables may be initialized by
arbitrary expressions involving constants, and previously declared
variables and functions." This would seem to imply that previously
declared variables would already have been initialized.

On the other hand, section 4.9 gives two examples:

binary(x, v, n)
int x, v[], n;
{
int low = 0;
int high = n - 1;
int mid;
...
}

and

binary(x, v, n)
int x, v[], n;
{
int low, high, mid;

low = 0;
high = n - 1;
...
}

and then goes on to say:

"In effect, initializations of automatic variables are just shorthand
for assignment statements. Which form to prefer is largely a matter
of taste. We have generally used explicit assignments, because
initializers in declarations are harder to see."

So it would appear that the reason K&R avoid using initializers was
not because there was something wrong with the way they worked, but
just for stylistic reasons, because they thought it was more readable
that way. (I tend to agree.)

For an assignment like our example that involves a nontrivial function
call, I think most people would not expect to see it in an
initializer, because oftentimes nontrivial function calls will require
more computations to be done first, even though this example happens
not to.

So that leaves us the choice of

int fd;
....
if ((fd = open(...)) < 0) fail();

or

int fd;
....
fd = open(...);
if (fd < 0) fail();

and the latter needs an extra line.

C99 gives us the option not to declare fd until just before we need
it, so we could write

.... lots of stuff ...
int fd = open(...);
if (fd < 0) fail();

but *that* is a relatively recent invention, and not necessarily
universally available.

> The style's only redeeming characteristic is you only need to read the big words
> - "if open PATH_UTMP", and you can scan over the rest and know by sight-reading
> they are the common open-a-file-and-fail-gracefully idiom.


That's a significant advantage, IMHO.
 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      08-06-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
>
> Crossposting this to comp.lang.c because it's become relevant.
>
> Our story so far, for c.l.c people:
>
> There is a discussion about the stylistic advantages and
> disadvantages of the following two snippets:
>
> void fooA(void) {
> int fd;
> if ((fd = open(...)) < 0) {
> fail();
> }
> }
>
> versus
>
> void fooB(void) {
> int fd = open(...);
> if (fd < 0) {
> fail();
> }
> }


Considering the crosspost, I won't complain about using the
non-standard open in place of fopen. However it is inappropriate
on comp.programming.

I have renamed the two functions. I consider fooA superior. I
disapprove of initialization code more complex than a simple value,
such as 0, and discourage even that. fooB must generate a call to
open, so it must generate code for that. That code is hidden from
the reader.

The only place, IMO, where initialization code is justified is
where the variable has the const characteristic applied. Then it
is necessary to install a value.

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

 
Reply With Quote
 
 
 
 
santosh
Guest
Posts: n/a
 
      08-06-2008
CBFalconer wrote:
> (E-Mail Removed) wrote:


>> void fooB(void) {
>> int fd = open(...);
>> if (fd < 0) {
>> fail();
>> }
>> }

>
> Considering the crosspost, I won't complain about using the
> non-standard open in place of fopen. However it is inappropriate
> on comp.programming.


You surely mean comp.lang.c?

<snip>

 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      08-06-2008
CBFalconer wrote:

> I have renamed the two functions. I consider fooA superior. I
> disapprove of initialization code more complex than a simple value,
> such as 0, and discourage even that.


You're bonkers.

Why /not/ initialise a variable when you declare it, with the value
you want it to have?

--
'It changed the future .. and it changed us.' /Babylon 5/

Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England

 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      08-06-2008
In article <(E-Mail Removed)>
<(E-Mail Removed)> wrote:
>There is a discussion about the stylistic advantages and disadvantages
>of the following two snippets:


[I did some editing in the quotes below, to be able to talk about
them better later.]

>void foo_set_and_test (void) {
> int fd;
> if ((fd = open(...)) < 0) {
> fail();
> }
>}
>
>versus
>
>void foo_init_and_then_test_separately (void) {
> int fd = open(...);
> if (fd < 0) {
> fail();
> }
>}
>
>Phlip prefers the latter, and claims that the former gained popularity
>because early versions of C did not guarantee the order in which
>initializations occurred,


As far as I know, no version of C, no matter how early and
not-even-K&R-1-compliant, did initializations in any order other
than "as they appear in the source". So:

void func(void) {
int a = init_a();
char *b = init_b();
double c = init_c(), d = init_d();
...
}

will always call init_a() first, then init_b(), then init_c(), then
init_d(), even in truly ancient implementations.

I have a slight preference for foo_init_and_then_test_separately()
myself, but this is a matter of taste. There is even a third
option:

void foo_set_and_then_test_separately(void) {
int fd;

fd = open(...);
if (fd < 0) {
fail();
...
}
...
}

which I slightly prefer over foo_init_and_then_test_separately()
(but only *very* slightly).

>[K&R-1] then goes on to say:
>
>"In effect, initializations of automatic variables are just shorthand
>for assignment statements. Which form to prefer is largely a matter
>of taste. We have generally used explicit assignments, because
>initializers in declarations are harder to see."
>
>So it would appear that the reason K&R avoid using initializers was
>not because there was something wrong with the way they worked, but
>just for stylistic reasons, because they thought it was more readable
>that way. (I tend to agree.)


As do I -- and I separate out the assignment and test when possible
as well, for the same reason. I will cram them together in
some cases, such as inside the control expression of a loop:

while ((c = getchar()) != EOF) {
...
}

because, while this is a bit hard to read, it is still easier to
read than the two obvious alternatives:

c = getchar();
while (c != EOF) {
...
c = getchar();
}

(which duplicates the "get a character" action, creating opportunities
for getting things wrong during code maintenance -- perhaps getchar()
needs to be replaced by get_from_file_while_maintaining_line_number()
or similar; and "continue" inside the loop is now bad), or:

while (c = getchar(), c != EOF) {
...
}

(which is readable but unusual, and requires duplicating the variable
name). If this last alternative were more commonly found in other
C code, I might use it, so this particular preference is more
historical than anything else.

Again, though, all of this is largely a matter of taste. Arguing
about it is like arguing whether raspberry ice cream is superior
to peach ice cream. (Answer: neither, chocolate is better )
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      08-06-2008
Chris Torek wrote:
> In article
> <(E-Mail Removed)>
> <(E-Mail Removed)> wrote:


<snip>

>>[K&R-1] then goes on to say:
>>
>>"In effect, initializations of automatic variables are just shorthand
>>for assignment statements. Which form to prefer is largely a matter
>>of taste. We have generally used explicit assignments, because
>>initializers in declarations are harder to see."
>>
>>So it would appear that the reason K&R avoid using initializers was
>>not because there was something wrong with the way they worked, but
>>just for stylistic reasons, because they thought it was more readable
>>that way. (I tend to agree.)

>
> As do I -- and I separate out the assignment and test when possible
> as well, for the same reason. I will cram them together in
> some cases, such as inside the control expression of a loop:
>
> while ((c = getchar()) != EOF) {
> ...
> }
>
> because, while this is a bit hard to read, it is still easier to
> read than the two obvious alternatives:
>
> c = getchar();
> while (c != EOF) {
> ...
> c = getchar();
> }
>
> (which duplicates the "get a character" action, creating opportunities
> for getting things wrong during code maintenance -- perhaps getchar()
> needs to be replaced by get_from_file_while_maintaining_line_number()
> or similar; and "continue" inside the loop is now bad), or:
>
> while (c = getchar(), c != EOF) {
> ...
> }
>
> (which is readable but unusual, and requires duplicating the variable
> name).


One other possibility:

for (c = getchar(); c != EOF; c = getchar()) { ... }

In general I have found that code consisting of (as far as is feasible)
simple expressions is better adaptable to restructuring and change than
code with lot of complex expressions. It's much like taking apart a car
made of Lego blocks versus a real one. Of course all code can't use
Lego blocks, but where possible...

<snip>

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      08-06-2008
santosh wrote:
> CBFalconer wrote:
>> (E-Mail Removed) wrote:

>
>>> void fooB(void) {
>>> int fd = open(...);
>>> if (fd < 0) {
>>> fail();
>>> }
>>> }

>>
>> Considering the crosspost, I won't complain about using the
>> non-standard open in place of fopen. However it is inappropriate
>> on comp.programming.

>
> You surely mean comp.lang.c?


No. My last sentence referred to the subject, not the open. My
fault for failing to be sufficiently specific. The question about
formatting was relevant on c.l.c.

You have confused things by snipping and failing to mark the
snipped area.

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


 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      08-06-2008
Chris Torek <(E-Mail Removed)> writes:
> <(E-Mail Removed)> wrote:
>>There is a discussion about the stylistic advantages and disadvantages
>>of the following two snippets:


[...]

>>void foo_set_and_test (void) {
>> int fd;
>> if ((fd = open(...)) < 0) {
>> fail();
>> }
>>}


[...]

>>void foo_init_and_then_test_separately (void) {
>> int fd = open(...);
>> if (fd < 0) {
>> fail();
>> }
>>}


[...]

> I have a slight preference for foo_init_and_then_test_separately()
> myself, but this is a matter of taste. There is even a third
> option:
>
> void foo_set_and_then_test_separately(void) {
> int fd;
>
> fd = open(...);
> if (fd < 0) {
> fail();
> ...
> }
> ...
> }


[...]

> Again, though, all of this is largely a matter of taste. Arguing
> about it is like arguing whether raspberry ice cream is superior
> to peach ice cream.


The last (two) variant(s) has(ve) the advantage that the value
assigned to fd can be inspected and possibly changed by a human using
a 'suitable tool' (debugger) before the program acts on it.
 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      08-06-2008
Rainer Weikusat wrote:

> Chris Torek writes:


>> int fd;
>> fd = open(...);


>> Again, though, all of this is largely a matter of taste. Arguing
>> about it is like arguing whether raspberry ice cream is superior
>> to peach ice cream.


> The last (two) variant(s) has(ve) the advantage that the value
> assigned to fd can be inspected and possibly changed by a human using
> a 'suitable tool' (debugger) before the program acts on it.


I suspect there are style guidelines saying "always initialize every variable".
Maybe they only apply to C++, and C is exempt.

--
Phlip
 
Reply With Quote
 
santosh
Guest
Posts: n/a
 
      08-06-2008
Phlip wrote:

> Rainer Weikusat wrote:
>
>> Chris Torek writes:

>
>>> int fd;
>>> fd = open(...);

>
>>> Again, though, all of this is largely a matter of taste. Arguing
>>> about it is like arguing whether raspberry ice cream is superior
>>> to peach ice cream.

>
>> The last (two) variant(s) has(ve) the advantage that the value
>> assigned to fd can be inspected and possibly changed by a human using
>> a 'suitable tool' (debugger) before the program acts on it.

>
> I suspect there are style guidelines saying "always initialize every
> variable". Maybe they only apply to C++, and C is exempt.


That cannot be, unless C forbids initialising every variable, which it
doesn't. In the dim and distant past I suppose variable redundant
initialisations were avoided due to efficiency concerns. These no
longer matter now, but some still prefer to avoid redundant
initialisations as an aesthetic choice.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: programi parsing question Phlip C Programming 41 08-15-2008 04:22 PM
[ANN] Parsing Tutorial and YARD 1.0: A C++ Parsing Framework Christopher Diggins C++ 0 07-09-2007 09:01 PM
[ANN] Parsing Tutorial and YARD 1.0: A C++ Parsing Framework Christopher Diggins C++ 0 07-09-2007 08:58 PM
SAX Parsing - Weird results when parsing content between tags. Naren XML 0 05-11-2004 07:25 PM
Perl expression for parsing CSV (ignoring parsing commas when in double quotes) GIMME Perl 2 02-11-2004 05:40 PM



Advertisments