Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #22223 > unrolled thread

What a stupid gcc!

Started byzgene <nospam@nospam.com>
First post2012-06-13 21:41 +0000
Last post2012-06-14 23:21 +0000
Articles 20 on this page of 97 — 29 participants

Back to article view | Back to comp.lang.c


Contents

  What a stupid gcc! zgene <nospam@nospam.com> - 2012-06-13 21:41 +0000
    Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-13 18:01 -0400
      Re: What a stupid gcc! Noob <root@127.0.0.1> - 2012-06-14 13:00 +0200
        Re: What a stupid gcc! Nomen Nescio <nobody@dizum.com> - 2012-06-14 14:33 +0200
          Re: What a stupid gcc! Rui Maciel <rui.maciel@gmail.com> - 2012-06-14 14:46 +0100
          Re: What a stupid gcc! Noob <root@127.0.0.1> - 2012-06-14 18:19 +0200
    Re: What a stupid gcc! Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-13 18:06 -0400
    Re: What a stupid gcc! jt@toerring.de (Jens Thoms Toerring) - 2012-06-13 22:19 +0000
      Re: What a stupid gcc! Rui Maciel <rui.maciel@gmail.com> - 2012-06-14 09:47 +0100
        Re: What a stupid gcc! Rui Maciel <rui.maciel@gmail.com> - 2012-06-14 14:37 +0100
    Re: What a stupid gcc! Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-06-13 17:05 -0600
    Re: What a stupid gcc! Nick Bowler <nbowler@draconx.ca> - 2012-06-14 00:09 +0000
    Re: What a stupid gcc! Varun Tewari <tewari.varun@gmail.com> - 2012-06-14 03:14 -0700
      Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-14 06:56 -0400
      Re: What a stupid gcc! Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-06-17 07:18 +0000
        Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-17 11:47 +0100
          Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-17 09:31 -0400
            Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-18 12:34 +0100
              Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-18 08:18 -0400
                Re: What a stupid gcc! gwowen <gwowen@gmail.com> - 2012-06-18 05:42 -0700
                  Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-18 09:39 -0400
                Re: What a stupid gcc! Rich Webb <bbew.ar@mapson.nozirev.ten> - 2012-06-18 09:06 -0400
                  Re: What a stupid gcc! ImpalerCore <jadill33@gmail.com> - 2012-06-18 07:18 -0700
              Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-19 00:13 -0700
                Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-19 11:28 +0100
                  Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 07:30 -0400
                  Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-20 00:16 -0700
          Re: What a stupid gcc! Rui Maciel <rui.maciel@gmail.com> - 2012-06-17 15:52 +0100
          Re: What a stupid gcc! Noob <root@localhost> - 2012-06-18 09:07 +0200
          Re: What a stupid gcc! Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-06-18 09:03 +0000
          Re: What a stupid gcc! Andrew Smallshaw <andrews@sdf.lonestar.org> - 2012-06-18 16:02 +0000
            Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-18 19:40 +0100
              Re: What a stupid gcc! Noob <root@localhost> - 2012-06-18 23:52 +0200
              Re: What a stupid gcc! Ike Naar <ike@iceland.freeshell.org> - 2012-06-18 23:09 +0000
                Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-19 01:30 +0100
                  Re: What a stupid gcc! Ian Collins <ian-news@hotmail.com> - 2012-06-19 13:03 +1200
                    Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 06:34 -0400
                  Re: What a stupid gcc! Ike Naar <ike@sverige.freeshell.org> - 2012-06-19 08:43 +0000
                    Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-19 11:00 +0100
                      Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 07:05 -0400
                      Re: What a stupid gcc! Ian Collins <ian-news@hotmail.com> - 2012-06-19 23:21 +1200
                        Re: What a stupid gcc! Ian Collins <ian-news@hotmail.com> - 2012-06-19 23:22 +1200
                      Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-19 13:45 +0100
                        Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-19 15:23 +0100
                          Re: What a stupid gcc! Ike Naar <ike@iceland.freeshell.org> - 2012-06-19 16:14 +0000
                            Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-19 18:01 +0100
                              Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 13:59 -0400
                              Re: What a stupid gcc! Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-06-19 15:29 -0600
                          Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-19 18:22 +0100
                            Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-19 21:13 +0100
                              Re: What a stupid gcc! Lew Pitcher <lpitcher@teksavvy.com> - 2012-06-19 16:27 -0400
                              Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 16:38 -0400
                                Re: What a stupid gcc! Kenneth Brody <kenbrody@spamcop.net> - 2012-06-20 09:47 -0400
                              Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-19 22:44 +0100
                                Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-21 01:39 -0700
                                  Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-21 10:55 +0100
                                    Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-21 04:11 -0700
                                      Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-21 12:36 +0100
                                        Re: What a stupid gcc! David Brown <david@westcontrol.removethisbit.com> - 2012-06-21 15:33 +0200
                                    Re: What a stupid gcc! Andrew Smallshaw <andrews@sdf.lonestar.org> - 2012-06-21 14:15 +0000
                              Re: What a stupid gcc! Kenneth Brody <kenbrody@spamcop.net> - 2012-06-20 09:37 -0400
                                Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-20 14:54 +0100
                                  Re: What a stupid gcc! Kenneth Brody <kenbrody@spamcop.net> - 2012-06-20 18:19 -0400
                                    Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-21 00:13 +0100
                                      Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-21 02:09 +0100
                                        Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-21 02:05 -0700
                                        Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-21 11:49 +0100
                                          Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-21 14:24 +0100
                                          Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-22 00:38 -0700
                                            Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-22 13:37 +0100
                                      Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-21 01:57 -0700
                                        Re: What a stupid gcc! "BartC" <bc@freeuk.com> - 2012-06-21 11:46 +0100
                                      Re: What a stupid gcc! Kenneth Brody <kenbrody@spamcop.net> - 2012-06-21 14:37 -0400
                                        Re: What a stupid gcc! Andrew Smallshaw <andrews@sdf.lonestar.org> - 2012-06-21 19:38 +0000
                                  Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-21 01:41 -0700
                                    Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-21 12:28 +0100
                Re: What a stupid gcc! Kaz Kylheku <kaz@kylheku.com> - 2012-06-19 15:05 +0000
          Re: What a stupid gcc! Ian Collins <ian-news@hotmail.com> - 2012-06-19 09:37 +1200
            Re: What a stupid gcc! ImpalerCore <jadill33@gmail.com> - 2012-06-18 15:18 -0700
            Re: What a stupid gcc! Paul J Gans <gansno@panix.com> - 2012-06-18 23:21 +0000
              Re: What a stupid gcc! Ian Collins <ian-news@hotmail.com> - 2012-06-19 11:26 +1200
                Re: What a stupid gcc! Paul J Gans <gansno@panix.com> - 2012-06-19 01:46 +0000
                  Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 07:19 -0400
                  Re: What a stupid gcc! Stephen Sprunk <stephen@sprunk.org> - 2012-06-19 08:01 -0500
                  Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 09:25 -0400
                    Re: What a stupid gcc! Les Cargill <lcargill99@comcast.com> - 2012-06-19 12:57 -0500
                      Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-19 14:59 -0400
              Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-19 01:36 +0100
                Re: What a stupid gcc! Paul J Gans <gansno@panix.com> - 2012-06-19 01:48 +0000
            Re: What a stupid gcc! Les Cargill <lcargill99@comcast.com> - 2012-06-18 19:50 -0500
            Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-19 00:19 -0700
              Re: What a stupid gcc! Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-19 12:56 +0100
                Re: What a stupid gcc! nick_keighley_nospam@hotmail.com - 2012-06-20 00:26 -0700
                  Re: What a stupid gcc! James Kuyper <jameskuyper@verizon.net> - 2012-06-20 06:31 -0400
        Re: What a stupid gcc! Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-06-18 00:18 -0600
          Re: What a stupid gcc! Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-06-18 09:15 +0000
    Re: What a stupid gcc! Kaz Kylheku <kaz@kylheku.com> - 2012-06-14 23:21 +0000

Page 3 of 5 — ← Prev page 1 2 [3] 4 5  Next page →


#22401

FromIan Collins <ian-news@hotmail.com>
Date2012-06-19 23:21 +1200
Message-ID<a4b5lqF7l4U4@mid.individual.net>
In reply to#22396
On 06/19/12 10:00 PM, BartC wrote:
> "Ike Naar"<ike@sverige.freeshell.org>  wrote in message
> news:slrn3vfsju0eu7.9cu.ike@sverige.freeshell.org...
>
>> In
>>
>>   int i, j, k;
>>   /* ... */
>>   for (i = 0; i<  N1; ++i)
>>     for (j = 0; j<  N2; ++j)
>>       for (k = 0; k<  N3; ++k)
>>         do_whatever_with(i, j, k);
>>
>> vs.
>>
>>   for (int i = 0; i<  N1; ++i)
>>     for (int j = 0; j<  N2; ++j)
>>       for (int k = 0; k<  N3; ++k)
>>         do_whatever_with(i, j, k);
>>
>> I don't see why the first variant would be an improvement
>> over the second one.
>
> (1) Imagine this 3-loop construction occurs half-a-dozen times in the
> function

Then it would get extracted into its own function.


-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#22402

FromIan Collins <ian-news@hotmail.com>
Date2012-06-19 23:22 +1200
Message-ID<a4b5o8F7l4U5@mid.individual.net>
In reply to#22401
On 06/19/12 11:21 PM, Ian Collins wrote:
> On 06/19/12 10:00 PM, BartC wrote:
>> "Ike Naar"<ike@sverige.freeshell.org>   wrote in message
>> news:slrn3vfsju0eu7.9cu.ike@sverige.freeshell.org...
>>
>>> In
>>>
>>>    int i, j, k;
>>>    /* ... */
>>>    for (i = 0; i<   N1; ++i)
>>>      for (j = 0; j<   N2; ++j)
>>>        for (k = 0; k<   N3; ++k)
>>>          do_whatever_with(i, j, k);
>>>
>>> vs.
>>>
>>>    for (int i = 0; i<   N1; ++i)
>>>      for (int j = 0; j<   N2; ++j)
>>>        for (int k = 0; k<   N3; ++k)
>>>          do_whatever_with(i, j, k);
>>>
>>> I don't see why the first variant would be an improvement
>>> over the second one.
>>
>> (1) Imagine this 3-loop construction occurs half-a-dozen times in the
>> function
>
> Then it would get extracted into its own function.

..and you wouldn't have three stale variables to clean up.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#22406

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-06-19 13:45 +0100
Message-ID<0.0ff9867a492014af7e6b.20120619134530BST.87395rsc5x.fsf@bsb.me.uk>
In reply to#22396
"BartC" <bc@freeuk.com> writes:

> "Ike Naar" <ike@sverige.freeshell.org> wrote in message
> news:slrn3vfsju0eu7.9cu.ike@sverige.freeshell.org...
>
>> In
>>
>>  int i, j, k;
>>  /* ... */
>>  for (i = 0; i < N1; ++i)
>>    for (j = 0; j < N2; ++j)
>>      for (k = 0; k < N3; ++k)
>>        do_whatever_with(i, j, k);
>>
>> vs.
>>
>>  for (int i = 0; i < N1; ++i)
>>    for (int j = 0; j < N2; ++j)
>>      for (int k = 0; k < N3; ++k)
>>        do_whatever_with(i, j, k);
>>
>> I don't see why the first variant would be an improvement
>> over the second one.

Sometimes I read something on c.l.c that takes my breath away.  This
following is one of those cases.

> (1) Imagine this 3-loop construction occurs half-a-dozen times in the
> function

OK, so you are going to list benefits predicated on having a truly
dreadful bit of code?

> (2) You would only need one 'int' declaration in the first variant, rather
> than 18.

That's a fact, but not in it self a benefit, unless I missed the "fewer
declarations are always better" rule.

> (3) The extra clutter in the second, is only telling you what you've already
> guessed,  that these loop indices are all ints.
>
> (4) But if you *did*, at some point, need to change the loop indices from
> int to something else, you've got eighteen times as much editing to
> do.

These two go together.  Something is clutter if all it does is confirm a
guess, yet it has the advantage that you can make that guess be wrong in
one simple edit.  Surely you'd now prefer all the 18 declarations so as
to preclude an incorrect guess.

I would change a declaration at the top of a function containing such
replicated code only with great trepidation and much checking.  Are all
the loops really the same in needing the new type?  Are i, j or k used
in any other way such that changing the type will cause a problem?  I'd
*much* rather make 18 edits to declarations with the smallest possible
scope so that I can review each one.

> (5) This would be bad practice, but if you ever found it necessary to goto
> from one loop body to another, the loop indices would be undefined.

This is not a serious suggestion.  You can't really want to say that a
single declaration is better because it eases that path of putting in
jumps from one loop body to another.  I think you just got carried away.

> (6) If you wanted to break out of any of the loops, and needed to refer to
> the value of the loop variable outside, it would either not exist, or be
> confused with a more global version.

The more breaks there are, the tighter the control I want on the scope
of identifiers.  You are right that you need to move the declaration out
of the loop, but that's not an argument that it should (a) be moved to
the top of encoding block, or (b) that it should have been there right
form the start.  It's pessimistic programming at its worst to think that
you'll be jumping all over the place and changing the types of loop
index variables so you might as well stick them together at the top
right away.

> (7) If ever needed to refer to one of the variables, either in a debugger,
> or on the phone to somebody, or in a note or email or comment, or even in a
> printf caption, then you've got a problem.

"Hey, you know that really crap function with 6 repeated triple-nested
loops?  The bounds for i in the third one are wrong."

I had to joke simply because I don't really understand this "benefit".
Surely with one shared declaration, whatever the problem is, it now
related to a use of the variable rather than the variable itself?

> Admittedly for the single bit of code in your example, it's not much of an
> issue. But for the more general case of having declarations scattered
> everywhere, identically-named variables shadowing each other in nested
> scopes, identically-named variables from different scopes getting mixed up
> (and what *does* happen when you goto from from block to another?), then
> I've already pointed out some problems elsewhere.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#22410

From"BartC" <bc@freeuk.com>
Date2012-06-19 15:23 +0100
Message-ID<jrq23v$rtv$1@dont-email.me>
In reply to#22406
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
news:0.0ff9867a492014af7e6b.20120619134530BST.87395rsc5x.fsf@bsb.me.uk...
> "BartC" <bc@freeuk.com> writes:

>> (1) Imagine this 3-loop construction occurs half-a-dozen times in the
>> function
>
> OK, so you are going to list benefits predicated on having a truly
> dreadful bit of code?

OK, just have two loops then. You can't say a function is terrible because
it's got two separate nested loops.

>> (2) You would only need one 'int' declaration in the first variant,
>> rather
>> than 18.
>
> That's a fact, but not in it self a benefit, unless I missed the "fewer
> declarations are always better" rule.

C clearly thinks it's a benefit; why else would the language allow you to
write:

 int x,y,z;

instead of:

 int x;
 int y;
 int z;

>> (5) This would be bad practice, but if you ever found it necessary to
>> goto
>> from one loop body to another, the loop indices would be undefined.
>
> This is not a serious suggestion.  You can't really want to say that a
> single declaration is better because it eases that path of putting in
> jumps from one loop body to another.  I think you just got carried away.

The real issue is to do with entering and leaving different scopes when goto
is used. I can see that that might have similar problems to a goto between
one function and another. With a single scope for the function, that doesn't
happen. Maybe goto shouldn't be used that way, but if it is, then it's
another headache to sort out.

>> (7) If ever needed to refer to one of the variables, either in a
>> debugger,
>> or on the phone to somebody, or in a note or email or comment, or even in
>> a
>> printf caption, then you've got a problem.
>
> "Hey, you know that really crap function with 6 repeated triple-nested
> loops?  The bounds for i in the third one are wrong."
>
> I had to joke simply because I don't really understand this "benefit".
> Surely with one shared declaration, whatever the problem is, it now
> related to a use of the variable rather than the variable itself?

My comment was serious. With a single lexical scope, each local variable has
a well-defined and unique qualifying path. With variables local to a block,
they now become anonymous, and you have the extra problem that each block
may be dynamically active or inactive, but no way of identifying any block.

Although, my argument against this is separate from the in-place
declarations; it would be possible to have those, and still have one lexical
scope for the function. Or perhaps I'm confused; if my understanding of how
it works is correct, the following code is wrong:

void fn(void){
int x=1,y=2;

if (x) {
 int z=3;
}
else {
 z=4;
}

printf("X,Y,Z = %d %d %d\n", x, y, z);
}

'z' is declared on it's first use, but because that happens inside a pair of
braces, then it's scope is limited to that block.

In that case, the problems are worse than I thought; if someone first
writes:

 if (x)
  int z=3;

then that's fine; but as soon as an extra statement is needed, and a {,}
block is created, it stops working! It sounds like a nightmare to me, but 
obviously people here seem to like it.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#22413

FromIke Naar <ike@iceland.freeshell.org>
Date2012-06-19 16:14 +0000
Message-ID<slrn3vfsju19bv.j4j.ike@iceland.freeshell.org>
In reply to#22410
On 2012-06-19, BartC <bc@freeuk.com> wrote:
> Although, my argument against this is separate from the in-place
> declarations; it would be possible to have those, and still have one lexical
> scope for the function. Or perhaps I'm confused; if my understanding of how
> it works is correct, the following code is wrong:
>
> void fn(void){
> int x=1,y=2;
>
> if (x) {
>  int z=3;
> }
> else {
>  z=4;

This is a syntax error; this z is undeclared.
The scope of the previous z ended at the closing brace of the block
where it was declared.

It is also a design error; if z is used in both branches of the
if statement, and also in the printf after the if statement,
it does not make sense to declare it in the first branch of the if statement,
it has to be declared at the level of the function body (where
the declarations of x and y are).
It only makes sense to declare z in the first branch of the if statement
if z is only used in that branch and nowhere else.

> }
>
> printf("X,Y,Z = %d %d %d\n", x, y, z);
> }
>
> 'z' is declared on it's first use, but because that happens inside a pair of
> braces, then it's scope is limited to that block.
>
> In that case, the problems are worse than I thought; if someone first
> writes:
>
>  if (x)
>   int z=3;

This is not valid C; the grammar for an if statement is

  if (expression) statement

or

  if (expression) statement else statement;

"int z=3;" is a declaration, not a statement.

A statement can be a compound statement, i.e.

  { block-item-list }

where a block-item-list is a list of block-item,
and block-item is either a statement or a declaration.
So, in order to have "int z=3;" after the "if (x)", there
has to be a brace-enclosed block:

  if (x)
  {
    int z=3;
  }

> then that's fine; but as soon as an extra statement is needed, and a {,}
> block is created, it stops working! It sounds like a nightmare to me, but 
> obviously people here seem to like it.

The situation that you describe can not occur. The brace-enclosed block
has to be there in the first place.

[toc] | [prev] | [next] | [standalone]


#22415

From"BartC" <bc@freeuk.com>
Date2012-06-19 18:01 +0100
Message-ID<jrqb9i$oop$1@dont-email.me>
In reply to#22413
"Ike Naar" <ike@iceland.freeshell.org> wrote in message
news:slrn3vfsju19bv.j4j.ike@iceland.freeshell.org...
> On 2012-06-19, BartC <bc@freeuk.com> wrote:

>> if my understanding of how
>> it works is correct, the following code is wrong:
>>
>> void fn(void){
>> int x=1,y=2;
>>
>> if (x) {
>>  int z=3;
>> }
>> else {
>>  z=4;
>
> This is a syntax error; this z is undeclared.
> The scope of the previous z ended at the closing brace of the block
> where it was declared.
>
> It is also a design error; if z is used in both branches of the
> if statement, and also in the printf after the if statement,
> it does not make sense to declare it in the first branch of the if
> statement,
> it has to be declared at the level of the function body (where
> the declarations of x and y are).

So, this is a restriction on the ability to be able to declare variables
'anywhere'. Either it's an immediate error (a later use of the variable
brings it up), or the later variable mistakenly uses a more global version
(for example, a file-scope variable), or it works, but subsequent editing
removes/introduces/moves blocks around. Then you really need to keep an eye
on those declarations.

I thought it was supposed to make life easier?

> It only makes sense to declare z in the first branch of the if statement
> if z is only used in that branch and nowhere else.

As I'd understood it (up to now anyway), you could turn the first assignment
to a variable, into a declaration.

>> }
>>
>> printf("X,Y,Z = %d %d %d\n", x, y, z);
>> }
>>
>> 'z' is declared on it's first use, but because that happens inside a pair
>> of
>> braces, then it's scope is limited to that block.
>>
>> In that case, the problems are worse than I thought; if someone first
>> writes:
>>
>>  if (x)
>>   int z=3;
>
> This is not valid C; the grammar for an if statement is
>
>  if (expression) statement

The following code compiles and works under Digital Mars' compiler:

void fn(void){
int x=1,y=2;

if (x)
 int z=3;
else {
 z=4;
}

printf("X,Y,Z = %d %d %d\n", x, y, z);
}

with a subsequent error after 'int z=3' is enclosed in braces.

> The situation that you describe can not occur. The brace-enclosed block
> has to be there in the first place.

Maybe that's another DMC bug. I couldn't reproduce it with other compilers,
but that might have been them rejecting such declarations anyway.

In any case, it does highlight some issues when trying to declare variables
at first use; it's not always possible, or introduces restrictions on use.

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#22418

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-06-19 13:59 -0400
Message-ID<4FE0BDEE.4000301@verizon.net>
In reply to#22415
On 06/19/2012 01:01 PM, BartC wrote:
> "Ike Naar" <ike@iceland.freeshell.org> wrote in message
> news:slrn3vfsju19bv.j4j.ike@iceland.freeshell.org...
...
>> It only makes sense to declare z in the first branch of the if statement
>> if z is only used in that branch and nowhere else.
> 
> As I'd understood it (up to now anyway), you could turn the first assignment
> to a variable, into a declaration.

You can, anywhere a declaration is permitted, but only if such a
declaration gives the variable's name sufficient scope to cover all
subsequent uses.

Declarations are permitted at file scope and as elements of blocks, but
there are a number of places in the grammar where a statement is
permitted, but a declaration is not: all declarations of x in following
lines are syntax errors:

        label: int x=0;

	if(i==3) int x=0;
	else double x = 0;

	while(a>3) int x = a--;

	do int x = a++;
	while(a < 100);

	for(int i=0; i<100; i++) int x = i;

	switch(a) int x=a;

	switch(b)
	{
	case 25: int x = a;
	    break;
	default: int x = b;
	}

Every one of those cases can be dealt with by enclosing the declaration
in a block; in which case it would have a scope restricted to that
block. That would be pretty pointless unless that same block also
contained at least one statement that actually uses the variable.

...
> The following code compiles and works under Digital Mars' compiler:
> 
> void fn(void){
> int x=1,y=2;
> 
> if (x)
>  int z=3;
> else {
>  z=4;
> }
> 
> printf("X,Y,Z = %d %d %d\n", x, y, z);
> }
> 
> with a subsequent error after 'int z=3' is enclosed in braces.

Then it's not a conforming C compiler. There are only two C grammar
productions for an if statement, and that code doesn't fit either one:

	if ( expression ) statement
	if ( expression ) statement else statement

"int z=3;" is a declaration, not a statement. C++ has a concept of a
declaration-statement, which does not exist in C, so

	if (x)
	    int z=3;

is permitted, but the C standard defines it as equivalent of

	if (x)
	{
	    int z=3;
	}

so we can't explain DMC's behavior by assuming that it follows C++ rules.

Such a declaration would be pretty pointless in C, even if it were
allowed. However, in C++, if z had a type with a non-trivial constructor
or a non-trivial destructor, such a declaration could actually make sense.

...
> Maybe that's another DMC bug. I couldn't reproduce it with other compilers,
> but that might have been them rejecting such declarations anyway.
> 
> In any case, it does highlight some issues when trying to declare variables
> at first use; it's not always possible, or introduces restrictions on use.

That's true, and well understood. Declaring variables at first use is
only possible when first use occurs at a location that would give the
variable sufficient scope to cover all subsequent uses. This is often
possible, but not always.

[toc] | [prev] | [next] | [standalone]


#22423

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2012-06-19 15:29 -0600
Message-ID<1blijjm1m5.fsf@pfeifferfamily.net>
In reply to#22415
"BartC" <bc@freeuk.com> writes:

> "Ike Naar" <ike@iceland.freeshell.org> wrote in message
> news:slrn3vfsju19bv.j4j.ike@iceland.freeshell.org...
>> On 2012-06-19, BartC <bc@freeuk.com> wrote:
>
>>> if my understanding of how
>>> it works is correct, the following code is wrong:
>>>
>>> void fn(void){
>>> int x=1,y=2;
>>>
>>> if (x) {
>>>  int z=3;
>>> }
>>> else {
>>>  z=4;
>>
>> This is a syntax error; this z is undeclared.
>> The scope of the previous z ended at the closing brace of the block
>> where it was declared.
>>
>> It is also a design error; if z is used in both branches of the
>> if statement, and also in the printf after the if statement,
>> it does not make sense to declare it in the first branch of the if
>> statement,
>> it has to be declared at the level of the function body (where
>> the declarations of x and y are).
>
> So, this is a restriction on the ability to be able to declare variables
> 'anywhere'. Either it's an immediate error (a later use of the variable
> brings it up), or the later variable mistakenly uses a more global version
> (for example, a file-scope variable), or it works, but subsequent editing
> removes/introduces/moves blocks around. Then you really need to keep an eye
> on those declarations.
>
> I thought it was supposed to make life easier?

You can declare variables essentially anywhere, but where you declare
does have actual meaning.

>> It only makes sense to declare z in the first branch of the if statement
>> if z is only used in that branch and nowhere else.
>
> As I'd understood it (up to now anyway), you could turn the first assignment
> to a variable, into a declaration.

You can.  But the declaration is only valid in the innermost block in
which it happens.

>>> }
>>>
>>> printf("X,Y,Z = %d %d %d\n", x, y, z);
>>> }
>>>
>>> 'z' is declared on it's first use, but because that happens inside a pair
>>> of
>>> braces, then it's scope is limited to that block.
>>>
>>> In that case, the problems are worse than I thought; if someone first
>>> writes:
>>>
>>>  if (x)
>>>   int z=3;
>>
>> This is not valid C; the grammar for an if statement is
>>
>>  if (expression) statement
>
> The following code compiles and works under Digital Mars' compiler:
>
> void fn(void){
> int x=1,y=2;
>
> if (x)
> int z=3;
> else {
> z=4;
> }
>
> printf("X,Y,Z = %d %d %d\n", x, y, z);
> }
>
> with a subsequent error after 'int z=3' is enclosed in braces.

Why does this surprise you?  In the code shown, the declaration is at
the level of the function -- the fact that it's in an if statement (but
not enclosed in a block) doesn't change that.  When you create a block
to put it in, it's only valid inside that block.

>> The situation that you describe can not occur. The brace-enclosed block
>> has to be there in the first place.
>
> Maybe that's another DMC bug. I couldn't reproduce it with other compilers,
> but that might have been them rejecting such declarations anyway.
>
> In any case, it does highlight some issues when trying to declare variables
> at first use; it's not always possible, or introduces restrictions on use.

The restrictions are there whether you're declaring at first use or not.

[toc] | [prev] | [next] | [standalone]


#22416

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-06-19 18:22 +0100
Message-ID<0.d63dfcbf17c321e1d55d.20120619182205BST.87pq8vqksi.fsf@bsb.me.uk>
In reply to#22410
"BartC" <bc@freeuk.com> writes:

> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
> news:0.0ff9867a492014af7e6b.20120619134530BST.87395rsc5x.fsf@bsb.me.uk...
>> "BartC" <bc@freeuk.com> writes:
>
>>> (1) Imagine this 3-loop construction occurs half-a-dozen times in the
>>> function
>>
>> OK, so you are going to list benefits predicated on having a truly
>> dreadful bit of code?
>
> OK, just have two loops then. You can't say a function is terrible because
> it's got two separate nested loops.

No, it goes down from "terrible" to just plain "dodgy".  Remember these
are triple-nested loops here.

>>> (2) You would only need one 'int' declaration in the first variant,
>>> rather
>>> than 18.
>>
>> That's a fact, but not in it self a benefit, unless I missed the "fewer
>> declarations are always better" rule.
>
> C clearly thinks it's a benefit; why else would the language allow you to
> write:
>
> int x,y,z;
>
> instead of:
>
> int x;
> int y;
> int z;

Eh?  Is the fact that C permits something to be taken as a sign that C
considered it to be a benefit?  C permits backwards gotos.  C permits
single-character variable names.  C permits multiple declarators in a
single declaration.  These things are not always good and they are not
always bad.  Saying "you only need one declaration rather six" does not
explain why one is better than six, unless there is some universal rule
that fewer is *always* better.

Personally, I don't see any advantage in simply reducing the number of
declarations at the expense of the size of their scope.

>>> (5) This would be bad practice, but if you ever found it necessary to
>>> goto
>>> from one loop body to another, the loop indices would be undefined.
>>
>> This is not a serious suggestion.  You can't really want to say that a
>> single declaration is better because it eases that path of putting in
>> jumps from one loop body to another.  I think you just got carried away.
>
> The real issue is to do with entering and leaving different scopes when goto
> is used. I can see that that might have similar problems to a goto between
> one function and another. With a single scope for the function, that doesn't
> happen. Maybe goto shouldn't be used that way, but if it is, then it's
> another headache to sort out.

So you are actually still saying that having one large-scope declaration
is better because it eases the introduction of gotos?  I don't have time
to answer that, so if that is your view, I'll just leave it as a
"difference of opinion".

>>> (7) If ever needed to refer to one of the variables, either in a
>>> debugger,
>>> or on the phone to somebody, or in a note or email or comment, or even in
>>> a
>>> printf caption, then you've got a problem.
>>
>> "Hey, you know that really crap function with 6 repeated triple-nested
>> loops?  The bounds for i in the third one are wrong."
>>
>> I had to joke simply because I don't really understand this "benefit".
>> Surely with one shared declaration, whatever the problem is, it now
>> related to a use of the variable rather than the variable itself?
>
> My comment was serious. With a single lexical scope, each local variable has
> a well-defined and unique qualifying path. With variables local to a block,
> they now become anonymous, and you have the extra problem that each block
> may be dynamically active or inactive, but no way of identifying any
> block.

No, still entirely baffled by what you obviously see as a problem.  I am
not being facetious -- I honestly don't know what you are saying here.
Maybe you could illustrate the problem with an example or two?

> Although, my argument against this is separate from the in-place
> declarations; it would be possible to have those, and still have one lexical
> scope for the function. Or perhaps I'm confused; if my understanding of how
> it works is correct, the following code is wrong:
>
> void fn(void){
> int x=1,y=2;
>
> if (x) {
> int z=3;
> }
> else {
> z=4;
> }
>
> printf("X,Y,Z = %d %d %d\n", x, y, z);
> }
>
> 'z' is declared on it's first use, but because that happens inside a pair of
> braces, then it's scope is limited to that block.
>
> In that case, the problems are worse than I thought; if someone first
> writes:
>
> if (x)
>  int z=3;
>
> then that's fine; but as soon as an extra statement is needed, and a {,}
> block is created, it stops working! It sounds like a nightmare to me,
> but obviously people here seem to like it.

I don't get this.  You say "the following code is wrong".  Yes, it's
wrong.  So what?  I don't know what criticism of mixing statements and
declarations I'm suppose to take from these erroneous fragments.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#22420

From"BartC" <bc@freeuk.com>
Date2012-06-19 21:13 +0100
Message-ID<jrqmir$7q2$1@dont-email.me>
In reply to#22416
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message 
news:0.d63dfcbf17c321e1d55d.20120619182205BST.87pq8vqksi.fsf@bsb.me.uk...
> "BartC" <bc@freeuk.com> writes:

>> then that's fine; but as soon as an extra statement is needed, and a {,}
>> block is created, it stops working! It sounds like a nightmare to me,
>> but obviously people here seem to like it.
>
> I don't get this.  You say "the following code is wrong".  Yes, it's
> wrong.  So what?
>  I don't know what criticism of mixing statements and
> declarations I'm suppose to take from these erroneous fragments.

I started my comments in this thread about the disadvantages of just 
declaring variables anywhere as needed.

Then I found out about block scopes and all the extra hassle they introduce, 
making such declarations even more problematic. (And why is a block so 
special anyway? Surely it's only used when you need two or more statements 
instead of one.)

I'm sorry if no-one else can see the problems (duplicate declarations, 
clutter, separating related variables, scattered declarations, trickier 
editing because you have to keep moving the declarations around, worrying 
about scope, shadowing, anonymity, etc).

My point of view is also an implementer's one: with variables declared at 
the top, the symbol table has a simple, tidy structure:

M       Module
  FN    Function
    A   Variable
    B   Variable
    C   Variable

Module M, function FN, containing variables A,B,C; very easy. Now you 
introduce block scopes, and multiple versions of 'A', 'B', 'C' all with 
different types, scopes and lifetimes. The symbol table is no longer so 
tidy, it now needs to be full of anonymous 'blocks'.

Given that the preference is this newsgroup is for small functions (usually 
small enough to fit in a window), what's the point of adding this extra 
complexity?

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#22421

FromLew Pitcher <lpitcher@teksavvy.com>
Date2012-06-19 16:27 -0400
Message-ID<5h5Er.7266$7y4.113@newsfe23.iad>
In reply to#22420
On Tuesday 19 June 2012 16:13, in comp.lang.c, bc@freeuk.com wrote:
[snip]
> I started my comments in this thread about the disadvantages of just
> declaring variables anywhere as needed.
> 
> Then I found out about block scopes and all the extra hassle they
> introduce, making such declarations even more problematic. (And why is a
> block so special anyway? Surely it's only used when you need two or more
> statements instead of one.)

That's one way of looking at it.

Another way to look at it would be that compound statements provide a level
of logical isolation that a single statement can't. They group together
multiple lines of code (declarations, statements) into a single entity, and
limit some of the side-effects of that entity.


[snip]
-- 
Lew Pitcher
"In Skills, We Trust"

[toc] | [prev] | [next] | [standalone]


#22422

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-06-19 16:38 -0400
Message-ID<4FE0E336.6060402@verizon.net>
In reply to#22420
On 06/19/2012 04:13 PM, BartC wrote:
...
> I started my comments in this thread about the disadvantages of just 
> declaring variables anywhere as needed.
> 
> Then I found out about block scopes and all the extra hassle they introduce, 
> making such declarations even more problematic. (And why is a block so 
> special anyway? Surely it's only used when you need two or more statements 
> instead of one.)

What makes blocks special is their use as function bodies, and as the
code controlled by selection statements (if, switch) and iteration
statements (while, do-while, and for). There are not many good reasons
for creating a block other than those. Those reasons alone are
sufficient to give most code a fair number of distinct blocks.

The relevance to variable scope is that it is commonplace, when using
blocks for those purposes, to have variables which are needed only in a
particular block, and by declaring them inside such blocks and having
their scope restricted to those blocks, you reduce the likelihood of
interfering with the definitions of variables in other blocks.

> I'm sorry if no-one else can see the problems (duplicate declarations, 
> clutter, separating related variables, scattered declarations, trickier 
> editing because you have to keep moving the declarations around, worrying 
> about scope, shadowing, anonymity, etc).

More accurately, I see most of the problems you've raised as positive
features. Duplicate definitions are good, precisely because they're
often not duplicates, but two different definitions of variables with
different meanings that should not be confused with each other, even if
you happened to make the mistake of giving them the same name.
Separating variables is good precisely because, if the appropriate scope
of those variables is in fact different, then they are usually
unrelated. If you tend to have a lot of related variables working
together with the same minimal scope, your program will often be
improved by putting those variables together in an aggregate: an array
or struct. Declarations are scattered to be close to their point of use,
where they're easier to find. Making editing difficult by requiring you
to move the declarations around is a good thing, because if you're doing
it a lot, something's wrong - you should give careful thought to each
such move. Having scope to worry about is a good thing - it means that
you can use a variable without worrying about the possibility that it
has already been used with some different meaning somewhere else in the
code. I've had to work on systems where all variables had global scope -
it's a nightmare.

[toc] | [prev] | [next] | [standalone]


#22434

FromKenneth Brody <kenbrody@spamcop.net>
Date2012-06-20 09:47 -0400
Message-ID<p5adnaPd8ocdSXzSnZ2dnUVZ_oGdnZ2d@bestweb.net>
In reply to#22422
On 6/19/2012 4:38 PM, James Kuyper wrote:
[...]
> What makes blocks special is their use as function bodies, and as the
> code controlled by selection statements (if, switch) and iteration
> statements (while, do-while, and for). There are not many good reasons
> for creating a block other than those. Those reasons alone are
> sufficient to give most code a fair number of distinct blocks.

I find it useful in "#if" blocks as well:

#if DEBUG_FOO
     {
     int i;
     unsigned char *pt;
     for ( i=0, pt=foo; i < len ; i++, pt++ )
         printf("%02x",*pt);
     printf("\n");
     }
#endif

[...]

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#22424

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-06-19 22:44 +0100
Message-ID<0.bc08f413c37d889e34d8.20120619224430BST.878vfjq8n5.fsf@bsb.me.uk>
In reply to#22420
"BartC" <bc@freeuk.com> writes:

> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
> news:0.d63dfcbf17c321e1d55d.20120619182205BST.87pq8vqksi.fsf@bsb.me.uk...
>> "BartC" <bc@freeuk.com> writes:
>
>>> then that's fine; but as soon as an extra statement is needed, and a {,}
>>> block is created, it stops working! It sounds like a nightmare to me,
>>> but obviously people here seem to like it.
>>
>> I don't get this.  You say "the following code is wrong".  Yes, it's
>> wrong.  So what?
>>  I don't know what criticism of mixing statements and
>> declarations I'm suppose to take from these erroneous fragments.
>
> I started my comments in this thread about the disadvantages of just
> declaring variables anywhere as needed.
>
> Then I found out about block scopes and all the extra hassle they
> introduce, making such declarations even more problematic. (And why is
> a block so special anyway? Surely it's only used when you need two or
> more statements instead of one.)
>
> I'm sorry if no-one else can see the problems (duplicate declarations,
> clutter, separating related variables, scattered declarations,
> trickier editing because you have to keep moving the declarations
> around, worrying about scope, shadowing, anonymity, etc).

As I said when I commented, I sometimes get the feeling that what we
both do (that we call programming) is, in fact, not similar at all.  I
don't split declarations unnecessarily and I don't separate related
ones.  What you call "scattered", I call tidy.  I don't think I spend
much time moving declarations around (but maybe I'm deluding myself on
that score) and I don't think I worry about scope.

Shadowing can occur using C90's rules and can even occur if you never
declare anything but at the top of a function.  I just don't do it, and
I don't recall it being a problem.  I don't know what the problem of
anonymity is.

> My point of view is also an implementer's one: with variables declared
> at the top, the symbol table has a simple, tidy structure:
>
> M       Module
>  FN    Function
>    A   Variable
>    B   Variable
>    C   Variable
>
> Module M, function FN, containing variables A,B,C; very easy. Now you
> introduce block scopes, and multiple versions of 'A', 'B', 'C' all
> with different types, scopes and lifetimes. The symbol table is no
> longer so tidy, it now needs to be full of anonymous 'blocks'.

It's stays simple if you allow the entries to be stacks: entering a new
scope just pushes the new data for that identifier.  In fact, it can
simplify your model, because there is no need for the function level.
I've done it a few times, and I don't recall it being any trouble.

> Given that the preference is this newsgroup is for small functions
> (usually small enough to fit in a window), what's the point of adding
> this extra complexity?

Extra complexity in the implementation is very low cost provided there
are lots of users.  The more work the implementation has to do (i.e. the
most sophisticated the language) the less work the programmer has to do
(in general).  Just allowing mixed declarations and code is neither much
work for the implementer, nor of much benefit to the programmer, so it's
not a particularly good example of the idea.  But since it is not hard
to do, I'd say "why not?" rather than "why?".

[1] More accurately, it is criticism of what C sometimes gets used for.
C should stay simple, but more code should be written in higher-level
languages that are harder to implement.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#22465

Fromnick_keighley_nospam@hotmail.com
Date2012-06-21 01:39 -0700
Message-ID<101c3431-45f6-4543-a0cb-a17493801734@googlegroups.com>
In reply to#22424
On Tuesday, June 19, 2012 10:44:30 PM UTC+1, Ben Bacarisse wrote:
> "BartC" <bc@freeuk.com> writes:
> > "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
> > news:0.d63dfcbf17c321e1d55d.20120619182205BST.87pq8vqksi.fsf@bsb.me.uk...
> >> "BartC" <bc@freeuk.com> writes:

> >>> then that's fine; but as soon as an extra statement is needed, and a {,}
> >>> block is created, it stops working! It sounds like a nightmare to me,
> >>> but obviously people here seem to like it.
> >>
> >> I don't get this.  You say "the following code is wrong".  Yes, it's
> >> wrong.  So what?
> >>  I don't know what criticism of mixing statements and
> >> declarations I'm suppose to take from these erroneous fragments.
> >
> > I started my comments in this thread about the disadvantages of just
> > declaring variables anywhere as needed.
> >
> > Then I found out about block scopes and all the extra hassle they
> > introduce,

*what* extra hassle?

> > making such declarations even more problematic. (And why is
> > a block so special anyway? 

why not? I think you've just discovered that auto variables are attached 
to *blocks* not just *function bodies*. Amazes me how people can program 
for years in the language and not know this! I guess they code by copy-paste 
rather than reading a manual or the language definition (C's official
definition is quite readable).

On an historical note. C is based on Algol-60 and Algol-60 allowed nested 
functions so nesting blocks with declarations probably didn't look so odd 
as you were already nesting functions with declarations. There are problems 
with nested functions and "global" variables.

int f ()
{
    int i = 1;

    int g ()
    {
        i = i + 1;
    }

    int h ()
    {
        int i = 2;
        g ();
    }

    print (i);
}

so which i is g() updating? Algol-60 answered "the one in h()" (dynamic scope) 
whilst Pascal answered "the one in f()" (lexical scope). C avoided the problem 
by disallowing nested functions- and you only occaisionally miss them.

> > Surely it's only used when you need two or
> > more statements instead of one.)

or wish to declare a local variable!

> > I'm sorry if no-one else can see the problems (duplicate declarations,

you can have those anyway with file and block scope and also function parameters.

> > clutter, 

I see no clutter

> > separating related variables, 

so don't do that

> > scattered declarations,

honest it isn't a problem!

> > trickier editing because you have to keep moving the declarations
> > around,

you're doing something wrong if you do this a lot.

> worrying about scope, shadowing,

I don't worry about these

> anonymity, etc).

and I don't even know what *that* is!

> As I said when I commented, I sometimes get the feeling that what we
> both do (that we call programming) is, in fact, not similar at all.  I
> don't split declarations unnecessarily and I don't separate related
> ones.  What you call "scattered", I call tidy.  I don't think I spend
> much time moving declarations around (but maybe I'm deluding myself on
> that score) and I don't think I worry about scope.

100% agree

> Shadowing can occur using C90's rules and can even occur if you never
> declare anything but at the top of a function.  I just don't do it, and
> I don't recall it being a problem.

I have done it and again I didn't notice a problem.

>  I don't know what the problem of anonymity is.
>
> > My point of view is also an implementer's one:

I've only limited interest in the implementor's problems

> > with variables declared
> > at the top, the symbol table has a simple, tidy structure:
> >
> > M       Module
> >  FN    Function
> >    A   Variable
> >    B   Variable
> >    C   Variable
> >
> > Module M, function FN, containing variables A,B,C; very easy. Now you
> > introduce block scopes, and multiple versions of 'A', 'B', 'C' all
> > with different types, scopes and lifetimes. The symbol table is no
> > longer so tidy, it now needs to be full of anonymous 'blocks'.

I don't think it was ever as tidy as you thought it was

int x;
int y;

int f (int x)
{
   int y;
}

int main (void)
{
   int x;
   
   f (x);
   f (y)
}

I'll note Algol-60 was invented in 1960 and *they* managed to implement it.
Admittedly "they" were really smart European computer scientists and 
mathematicians.

> It's stays simple if you allow the entries to be stacks: entering a new
> scope just pushes the new data for that identifier.  In fact, it can
> simplify your model, because there is no need for the function level.

exactly

> I've done it a few times, and I don't recall it being any trouble.
>
> > Given that the preference is this newsgroup is for small functions
> > (usually small enough to fit in a window), what's the point of adding
> > this extra complexity?

it isn't really any increase in complexity. And again note 
*** this is not a new feature*** C always worked this way!
But yes with small functions the need for it lessens.

> Extra complexity in the implementation is very low cost provided there
> are lots of users.  The more work the implementation has to do (i.e. the
> most sophisticated the language) the less work the programmer has to do
> (in general).  Just allowing mixed declarations and code is neither much
> work for the implementer, nor of much benefit to the programmer,

C++ programmers would disagree

> so it's
> not a particularly good example of the idea.  But since it is not hard
> to do, I'd say "why not?" rather than "why?".
> 
> [1] More accurately, it is criticism of what C sometimes gets used for.
> C should stay simple, but more code should be written in higher-level
> languages that are harder to implement.

the reverse logic is to do everything in Dartmouth BASIC. Note sophisticated 
languages aren't always harder to implement. FORTRAN IV was notoriously difficult 
to implement and program in because of its poor orthogonality.

An example where block scope makes sense in C++ :-

void func ()
{
    {
        Lock lock (table_semaphore);
        do_stuff_on_locked_table();
        do_more_stuff_on_locked_table();
    }
    
    long_operation_without_lock()
}

Lock's destructor cleans up the semaphore

[toc] | [prev] | [next] | [standalone]


#22472

From"BartC" <bc@freeuk.com>
Date2012-06-21 10:55 +0100
Message-ID<jruu97$dg8$1@dont-email.me>
In reply to#22465
<nick_keighley_nospam@hotmail.com> wrote in message
news:101c3431-45f6-4543-a0cb-a17493801734@googlegroups.com...
> On Tuesday, June 19, 2012 10:44:30 PM UTC+1, Ben Bacarisse wrote:
>> "BartC" <bc@freeuk.com> writes:

>> > with variables declared
>> > at the top, the symbol table has a simple, tidy structure:
>> >
>> > M       Module
>> >  FN    Function
>> >    A   Variable
>> >    B   Variable
>> >    C   Variable

> I don't think it was ever as tidy as you thought it was
>
> int x;
> int y;
>
> int f (int x)
> {
>   int y;
> }
>
> int main (void)
> {
>   int x;
>
>   f (x);
>   f (y)
> }

You get this instead:

M         module
  X       var
  Y       var
  F       fn
    X     param
    Y     var
  MAIN    fn
    X     var

Still tidy in that the structure simply reflects the hierarchy in the
program. If you wanted, at the end of the compilation, a list of all
variables in a function, it's easy; for main(), it's just main:(X). Now
change your main() function to:

 int main (void)
 {
   int x;

   if (x) {
    int x=3;
    f(x);
   }

   f (x);
   f (y)
 }

and the last part of the table becomes:

MAIN    fn
  ?     block
    X   var
  X     var

What goes in place of ? It would need to be some internal name such as
block#001. That list of variables now becomes ((block#001: (X)),X); it's not
a simple list anymore, and you have a set of anonymous blocks with
meaningless names.

>> It's stays simple if you allow the entries to be stacks: entering a new
>> scope just pushes the new data for that identifier.  In fact, it can
>> simplify your model, because there is no need for the function level.
>
> exactly

A stack is a dynamic structure. Suppose you want to retain all details of
all variables at the end of compilation, for debugging purposes for example?

> An example where block scope makes sense in C++ :-
>
> void func ()
> {
>    {
>        Lock lock (table_semaphore);
>        do_stuff_on_locked_table();
>        do_more_stuff_on_locked_table();
>    }
>
>    long_operation_without_lock()
> }
>
> Lock's destructor cleans up the semaphore

Which exposes another problem with block-variables: there might be extra
overheads in allocating, initialising and freeing them on each entry and 
exit to the block. For each time a function is called, a block might be
executed millions of times. (I'm sure most uses will optimised out, so 
variables are allocated at function-entry, but it's something else to keep 
in mind.)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#22475

Fromnick_keighley_nospam@hotmail.com
Date2012-06-21 04:11 -0700
Message-ID<8e4bbe25-c50a-472c-b918-b28beb24d216@googlegroups.com>
In reply to#22472
On Thursday, June 21, 2012 10:55:35 AM UTC+1, Bart wrote:
> <nick_keighley_nospam@hotmail.com> wrote in message
> news:101c3431-45f6-4543-a0cb-a17493801734@googlegroups.com...
> > On Tuesday, June 19, 2012 10:44:30 PM UTC+1, Ben Bacarisse wrote:
> >> "BartC" <bc@freeuk.com> writes:

> >> > with variables declared
> >> > at the top, the symbol table has a simple, tidy structure:
> >> >
> >> > M       Module
> >> >  FN    Function
> >> >    A   Variable
> >> >    B   Variable
> >> >    C   Variable
> 
> > I don't think it was ever as tidy as you thought it was
> >
> > int x;
> > int y;
> >
> > int f (int x)
> > {
> >   int y;
> > }
> >
> > int main (void)
> > {
> >   int x;
> >
> >   f (x);
> >   f (y)
> > }
> 
> You get this instead:
> 
> M         module
>   X       var
>   Y       var
>   F       fn
>     X     param
>     Y     var
>   MAIN    fn
>     X     var
> 
> Still tidy in that the structure simply reflects the hierarchy in the
> program.

Do real programming languages actually implement symbol tables like this?

> If you wanted, at the end of the compilation, a list of all
> variables in a function, it's easy; for main(), it's just main:(X). Now
> change your main() function to:
> 
>  int main (void)
>  {
>    int x;
> 
>    if (x) {
>     int x=3;
>     f(x);
>    }
> 
>    f (x);
>    f (y)
>  }
> 
> and the last part of the table becomes:
> 
> MAIN    fn
>   ?     block
>     X   var
>   X     var
> 
> What goes in place of ? It would need to be some internal name such as
> block#001. That list of variables now becomes ((block#001: (X)),X); it's not
> a simple list anymore, and you have a set of anonymous blocks with
> meaningless names.

I think your scheme only works with FORTRAN. All bets are off as soon as recursion is introduced.

> >> It's stays simple if you allow the entries to be stacks: entering a new
> >> scope just pushes the new data for that identifier.  In fact, it can
> >> simplify your model, because there is no need for the function level.
> >
> > exactly
> 
> A stack is a dynamic structure. Suppose you want to retain all details of
> all variables at the end of compilation, for debugging purposes for example?

you don't write recursive programs do you?

> > An example where block scope makes sense in C++ :-
> >
> > void func ()
> > {
> >    {
> >        Lock lock (table_semaphore);
> >        do_stuff_on_locked_table();
> >        do_more_stuff_on_locked_table();
> >    }
> >
> >    long_operation_without_lock()
> > }
> >
> > Lock's destructor cleans up the semaphore
> 
> Which exposes another problem with block-variables: there might be extra
> overheads in allocating, initialising and freeing them on each entry and 
> exit to the block. 

usually not. The block structure is actually static so the space can be allocated on entry to the function.

> For each time a function is called, a block might be
> executed millions of times. (I'm sure most uses will optimised out, so 
> variables are allocated at function-entry, but it's something else to keep 
> in mind.)

in C++ the CTORs and DTORs have to be executed and that may be expensive. C++ programmers have to take more care.

[toc] | [prev] | [next] | [standalone]


#22478

From"BartC" <bc@freeuk.com>
Date2012-06-21 12:36 +0100
Message-ID<jrv15r$sii$1@dont-email.me>
In reply to#22475
<nick_keighley_nospam@hotmail.com> wrote in message 
news:8e4bbe25-c50a-472c-b918-b28beb24d216@googlegroups.com...
> On Thursday, June 21, 2012 10:55:35 AM UTC+1, Bart wrote:
>> <nick_keighley_nospam@hotmail.com> wrote in message
>> news:101c3431-45f6-4543-a0cb-a17493801734@googlegroups.com...
>> > On Tuesday, June 19, 2012 10:44:30 PM UTC+1, Ben Bacarisse wrote:
>> >> "BartC" <bc@freeuk.com> writes:

>> >> >
>> >> > M       Module
>> >> >  FN    Function
>> >> >    A   Variable
>> >> >    B   Variable
>> >> >    C   Variable
>>
>> > I don't think it was ever as tidy as you thought it was

> Do real programming languages actually implement symbol tables like this?

Real program in a module called 'm' (return value of function edited out):

function fn =
 var a,b,c
end

Real extract from the symbol table (extraneous matter edited out):

$root-----------Root
  m---------------Module
    fn--------------Proc
      a---------------Frame
      b---------------Frame
      c---------------Frame

It might not be mainstream, but it's a real enough language. But why 
shouldn't a symbol table look like this? (Obviously, the internal structure 
is more elaborate, but following the hierarchical links starting from $root, 
you get the above layout.)

> I think your scheme only works with FORTRAN. All bets are off as soon as 
> recursion is introduced.

Perhaps we're talking at cross-purposes then. What has recursion in the 
language being compiled, got to do with any of this?

Remember these symbol tables represent the static, lexical structure of all 
entities defined in the source code. They don't describe the run-time 
call-tree.

>> A stack is a dynamic structure. Suppose you want to retain all details of
>> all variables at the end of compilation, for debugging purposes for 
>> example?
>
> you don't write recursive programs do you?

Only compilers.

>> Which exposes another problem with block-variables: there might be extra
>> overheads in allocating, initialising and freeing them on each entry and
>> exit to the block.

> usually not. The block structure is actually static so the space can be 
> allocated on entry to the function.

Thanks. Somebody has finally admitted that function entry and exit is where 
these things naturally belong...

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#22482

FromDavid Brown <david@westcontrol.removethisbit.com>
Date2012-06-21 15:33 +0200
Message-ID<0MudnbucLLw6vn7SnZ2dnUVZ7t-dnZ2d@lyse.net>
In reply to#22478
On 21/06/2012 13:36, BartC wrote:
> <nick_keighley_nospam@hotmail.com> wrote in message
> news:8e4bbe25-c50a-472c-b918-b28beb24d216@googlegroups.com...
>> On Thursday, June 21, 2012 10:55:35 AM UTC+1, Bart wrote:
>>> <nick_keighley_nospam@hotmail.com> wrote in message
>>> news:101c3431-45f6-4543-a0cb-a17493801734@googlegroups.com...
>>> > On Tuesday, June 19, 2012 10:44:30 PM UTC+1, Ben Bacarisse wrote:
>>> >> "BartC" <bc@freeuk.com> writes:
>
>>> >> >
>>> >> > M       Module
>>> >> >  FN    Function
>>> >> >    A   Variable
>>> >> >    B   Variable
>>> >> >    C   Variable
>>>
>>> > I don't think it was ever as tidy as you thought it was
>
>> Do real programming languages actually implement symbol tables like this?
>
> Real program in a module called 'm' (return value of function edited out):
>
> function fn =
> var a,b,c
> end
>
> Real extract from the symbol table (extraneous matter edited out):
>
> $root-----------Root
>   m---------------Module
>     fn--------------Proc
>       a---------------Frame
>       b---------------Frame
>       c---------------Frame
>
> It might not be mainstream, but it's a real enough language. But why
> shouldn't a symbol table look like this? (Obviously, the internal
> structure is more elaborate, but following the hierarchical links
> starting from $root, you get the above layout.)
>
>> I think your scheme only works with FORTRAN. All bets are off as soon
>> as recursion is introduced.
>
> Perhaps we're talking at cross-purposes then. What has recursion in the
> language being compiled, got to do with any of this?
>
> Remember these symbol tables represent the static, lexical structure of
> all entities defined in the source code. They don't describe the
> run-time call-tree.
>
>>> A stack is a dynamic structure. Suppose you want to retain all
>>> details of
>>> all variables at the end of compilation, for debugging purposes for
>>> example?
>>
>> you don't write recursive programs do you?
>
> Only compilers.
>
>>> Which exposes another problem with block-variables: there might be extra
>>> overheads in allocating, initialising and freeing them on each entry and
>>> exit to the block.
>
>> usually not. The block structure is actually static so the space can
>> be allocated on entry to the function.
>
> Thanks. Somebody has finally admitted that function entry and exit is
> where these things naturally belong...
>

You are mixing up allocation with scope and access control.

Think of it this way.  The blocks of a function form a tree.  Each node 
has some sort of identifier number when it is created.  Each time you 
make a new variable within a block, the variable's internal name is 
augmented with the node id.  The if you want to do the allocation in a 
single place at the function entry, that's fine - each block-local 
variable is independent because it has a different internal name.  And 
when you (the compiler) come across a variable in a block, you use the 
block's node id, and the node ids of its parents, to look up the correct 
internal name.

Of course, real compilers are a bit more sophisticated, and will 
allocate variables to registers rather than stacks, re-use the registers 
(or stack slots), optimise them away altogether, or delay stack 
allocation until the variable is actually used.

[toc] | [prev] | [next] | [standalone]


#22483

FromAndrew Smallshaw <andrews@sdf.lonestar.org>
Date2012-06-21 14:15 +0000
Message-ID<slrn3vfsju6b4v.9rg.andrews@sdf.lonestar.org>
In reply to#22472
On 2012-06-21, BartC <bc@freeuk.com> wrote:
>
> and the last part of the table becomes:
>
> MAIN    fn
>   ?     block
>     X   var
>   X     var
>
> What goes in place of ? It would need to be some internal name such as
> block#001. That list of variables now becomes ((block#001: (X)),X); it's not
> a simple list anymore, and you have a set of anonymous blocks with
> meaningless names.

Have you never written a recursive function?  You have exactly the
same issues, compounded by identical line numbers and the inevitable
masking of variables.  Aside from what is essentially criticism of
structured programming generally (seriously guys, that argument
was lost thrity years ago)  a lot of the specific criticism of this
aspect has implicitly assumed that masking one variable with another
is intentional - it's not, in fact intentionally doing so would
generally be bad practice.  Like any language feature it is of no
use against a c.l.c.er determined to write contrived poor code.  It
is simply an additional protection against ill-considered external
modification, and better bringing the logical and physical extents
of a variable into alignment.

For example, consider the statement "int error_code;".  We can
naturally infer upon reading it in a source listing that is contains
some kind of code describing an error condition.  It's behaviour
when there is an error should be easily determined, but what does
it contain in the _absence_ of an error?  Does it contain anything?
Has it been initialised to some "No error" value that is actually
depended on for normal operation?  Has it been "borrowed" by a
programmer who didn't understand block level declarations?

These are the kind of thing that need a lot of careful examination
to determine and add a lot of mental overhead to the programmer.
They are also issues that simply don't arise if the variable doesn't
exist until such time as there is an error.

-- 
Andrew Smallshaw
andrews@sdf.lonestar.org

[toc] | [prev] | [next] | [standalone]


Page 3 of 5 — ← Prev page 1 2 [3] 4 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web