By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,341 Members | 1,410 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,341 IT Pros & Developers. It's quick & easy.

Scope of block-local variables

P: n/a
In the following code, what is the scope of the variables?

int main(void)
{
int var;
for (var = 0; var < 10; ++var)
{
int var = var + 5;
printf("%d\n", var);
}
return 0;
}

I'm certain that I have read (here in clc) that a variable's scope
doesn't start until the end of its definition, so saying

int var = var + 5;

is valid and sets the block-local variable var to the value of the outer
variable var. However, GCC (2.95.4, 3.0.4, 3.3.3) disagrees with me.
Have I got confused, or is GCC broken in that way?

(Yes, that code is confusing. However, there are times, like in a
function-like macro, when it can occur.)

Chris C
Nov 14 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Chris Croughton <ch***@keristor.net> wrote:
int main(void)
{
int var;
for (var = 0; var < 10; ++var)
{
int var = var + 5;
printf("%d\n", var);
}
return 0;
} I'm certain that I have read (here in clc) that a variable's scope
doesn't start until the end of its definition, so saying
The scope of a variable starts where its complete declarator ends
(cf. 6.2.1#7 and 6.7.5), which for inner `var' is:
int var
(the things after that are "=" and initializer).
int var = var + 5; is valid and sets the block-local variable var to the value of the outer
variable var. However, GCC (2.95.4, 3.0.4, 3.3.3) disagrees with me.
Have I got confused, or is GCC broken in that way?


GCC is right.

I haven't found any nice example in the C Std, so I'll quote
one from C++:
The point of declaration for a name is immediately after its complete
declarator (clause 8) and before its initializer (if any), except as
noted below. [Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value. ]

+++++

As a bonus, for VLA I think this should be correct:
int var = 7;
{
double var[var]; //second var refers to outer int var
}

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #2

P: n/a
On 27 Nov 2004 16:15:02 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
I'm certain that I have read (here in clc) that a variable's scope
doesn't start until the end of its definition, so saying
The scope of a variable starts where its complete declarator ends
(cf. 6.2.1#7 and 6.7.5), which for inner `var' is:
int var
(the things after that are "=" and initializer).


Ah, I was confusing its declaration with the definition. I never have
got those two straight (my gut feeling is that the meanings are the
other way round).
int var = var + 5;

is valid and sets the block-local variable var to the value of the outer
variable var. However, GCC (2.95.4, 3.0.4, 3.3.3) disagrees with me.
Have I got confused, or is GCC broken in that way?


GCC is right.


However,

int Mongolia = 1;
{
int war = Mongolia, Mongolia = war;
...
}

has the intended effect, because war is declared and set to Outer
Mongolia before Inner Mongolia is declared and set to war (and hence to
Outer Mongolia). Which is what I want for macros to force single
evaluation of the arguments without having name clashes...

(No, I haven't been drinking. Perhaps I should...)
I haven't found any nice example in the C Std, so I'll quote
one from C++:
The point of declaration for a name is immediately after its complete
declarator (clause 8) and before its initializer (if any), except as
noted below. [Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value. ]
I couldn't find it in the C standard, either.
+++++

As a bonus, for VLA I think this should be correct:
int var = 7;
{
double var[var]; //second var refers to outer int var
}


Yes, I think it should. Whether it works for any particular compiler is
left as an exercise for the reader.

Thanks...

Chris C
Nov 14 '05 #3

P: n/a
Chris Croughton <ch***@keristor.net> wrote:
On 27 Nov 2004 16:15:02 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
The scope of a variable starts where its complete declarator ends
(cf. 6.2.1#7 and 6.7.5), which for inner `var' is:
int var


Sorry, I was wrong here (cf. 6.7 and 6.7.5). In declaration
int var = 5;
the declarator is:
var
Ah, I was confusing its declaration with the definition.
No, you confuse declarator with declaration.

*Declaration* is a form which introduces a name into a scope (declarations
can be nested - eg. function declaration may declare its parameters).

Declaration is a *definition*, when it defines an object of function
(6.7#5) (every definition is a declaration, but some declarations are
not definitions).

*Declarator* is just part of declaration which includes the identifier
(name) and its type category (and may include nested declarations).
extern int const * const * p; //declarator: * const * p
int f(double d) {/*...*/} //declarator: f(double d)
I don't think we need the idea of "declarator" for anything other
than grammatical analysis.

(Funny thing is that in 6.7 the syntax for a declaration does not
encompass function definition, which is actually directly admitted
in the footnote.)

int Mongolia = 1;
{
int war = Mongolia, Mongolia = war;
...
} has the intended effect,
Yes.
because war is declared and set to Outer
Mongolia before Inner Mongolia is declared and set to war (and hence to
Outer Mongolia).
:-)
Which is what I want for macros to force single
evaluation of the arguments without having name clashes...


Now this is interesting, how do you manage to do it?

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #4

P: n/a
On 27 Nov 2004 20:49:59 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
Chris Croughton <ch***@keristor.net> wrote:
On 27 Nov 2004 16:15:02 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
> The scope of a variable starts where its complete declarator ends
> (cf. 6.2.1#7 and 6.7.5), which for inner `var' is:
> int var
Sorry, I was wrong here (cf. 6.7 and 6.7.5). In declaration
int var = 5;
the declarator is:
var


OK, but the point (for me) is that it is complete when var has been
completely declared and before it is initialised..
Ah, I was confusing its declaration with the definition.


No, you confuse declarator with declaration.

*Declaration* is a form which introduces a name into a scope (declarations
can be nested - eg. function declaration may declare its parameters).

Declaration is a *definition*, when it defines an object of function
(6.7#5) (every definition is a declaration, but some declarations are
not definitions).

*Declarator* is just part of declaration which includes the identifier
(name) and its type category (and may include nested declarations).
extern int const * const * p; //declarator: * const * p
int f(double d) {/*...*/} //declarator: f(double d)
I don't think we need the idea of "declarator" for anything other
than grammatical analysis.


Ah, right. I think the terms are confusing anyway. And have done since
I encountered them in K&R almost 30 years ago...
(Funny thing is that in 6.7 the syntax for a declaration does not
encompass function definition, which is actually directly admitted
in the footnote.)


Hmm. Perhaps they had trouble with it as well <g>...
because war is declared and set to Outer
Mongolia before Inner Mongolia is declared and set to war (and hence to
Outer Mongolia).


:-)


I started thinking in English and the Outer and Inner suggested Mongolia
<g>. Then declaring war was inevitable <g>...
Which is what I want for macros to force single
evaluation of the arguments without having name clashes...


Now this is interesting, how do you manage to do it?


It turns out that the way I thought of doing it still doesn't work.
However, it does mean that I can give the first variable a name no one
would ever use (_XyZzY_24C41_PlUgH_) and then use a shorter one (like
'i') in the rest of the macro.

Chris C
Nov 14 '05 #5

P: n/a
Chris Croughton <ch***@keristor.net> wrote:
On 27 Nov 2004 20:49:59 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
Chris Croughton <ch***@keristor.net> wrote:
Which is what I want for macros to force single
evaluation of the arguments without having name clashes... Now this is interesting, how do you manage to do it?

It turns out that the way I thought of doing it still doesn't work.
Ha, I knew it! :-D
However, it does mean that I can give the first variable a name no one
would ever use (_XyZzY_24C41_PlUgH_) and then use a shorter one (like
'i') in the rest of the macro.


All identifiers with regexps __.* and _[[:upper:]].* are reserved,
so I would change your name to _xyZzY_24C41_PlUgH_ (I stumbled on it
once, so I'm careful ever since).

I believe "no one would ever use" is the only technique.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #6

P: n/a
On 27 Nov 2004 22:34:49 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
Chris Croughton <ch***@keristor.net> wrote:
On 27 Nov 2004 20:49:59 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
> Chris Croughton <ch***@keristor.net> wrote: >> Which is what I want for macros to force single
>> evaluation of the arguments without having name clashes...
> Now this is interesting, how do you manage to do it?
It turns out that the way I thought of doing it still doesn't work.
Ha, I knew it! :-D


I thought "Ah, that solves it" but like a lot of 'eureka' monoents it
didn't last.
However, it does mean that I can give the first variable a name no one
would ever use (_XyZzY_24C41_PlUgH_) and then use a shorter one (like
'i') in the rest of the macro.


All identifiers with regexps __.* and _[[:upper:]].* are reserved,
so I would change your name to _xyZzY_24C41_PlUgH_ (I stumbled on it
once, so I'm careful ever since).


Oops, that's true. Just invert the case. The centre part should, of
course, been 124C_41...

I seem to remember that at one time identifiers with the form

str[[:lower:]].*

were also reserved (and possibly some other prefixes used by library
functions) but can't find that in the C99 spec. Was this true, or was
it someone's extension?
I believe "no one would ever use" is the only technique.


Indeed. What I really want is inline template functions, but even if
they were in C (and I don't seriously think that they should be) in a
future standard I still couldn't use them until all previous compilers
had become unused...

Chris C
Nov 14 '05 #7

P: n/a
On Sun, 28 Nov 2004 12:35:35 +0000, in comp.lang.c , Chris Croughton
<ch***@keristor.net> wrote:
I seem to remember that at one time identifiers with the form

str[[:lower:]].*

were also reserved (and possibly some other prefixes used by library
functions) but can't find that in the C99 spec. Was this true, or was
it someone's extension?


7.26 Future library directions
All external names described below are reserved no matter what headers are
included by the program.
.....
7.26.11 String handling <string.h>
1 Function names that begin with str, mem, or wcs and a lowercase letter
may be added to the declarations in the <string.h> header.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
Nov 14 '05 #8

P: n/a
Chris Croughton <ch***@keristor.net> wrote:
On 27 Nov 2004 22:34:49 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
Chris Croughton <ch***@keristor.net> wrote:
On 27 Nov 2004 20:49:59 GMT, S.Tobias
<si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
> Chris Croughton <ch***@keristor.net> wrote:

All identifiers with regexps __.* and _[[:upper:]].* are reserved,


Me wrong again: ^__.* and ^_[[:upper:]].*
Oops, that's true. Just invert the case. The centre part should, of
course, been 124C_41...


The center was all right, it's what starts and identifier that counts.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.