Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #22223 > unrolled thread
| Started by | zgene <nospam@nospam.com> |
|---|---|
| First post | 2012-06-13 21:41 +0000 |
| Last post | 2012-06-14 23:21 +0000 |
| Articles | 20 on this page of 97 — 29 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | Lew Pitcher <lpitcher@teksavvy.com> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2012-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-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]
| From | nick_keighley_nospam@hotmail.com |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | nick_keighley_nospam@hotmail.com |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | David Brown <david@westcontrol.removethisbit.com> |
|---|---|
| Date | 2012-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]
| From | Andrew Smallshaw <andrews@sdf.lonestar.org> |
|---|---|
| Date | 2012-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