static allocation question...

F

FMorales

-- I didn't notice anything about this specifically
-- in the c.l.c. FAQ, nor could i get a strait answere
-- from my copy of the C standard. Hopeing someone
-- here could shed some light on it :)...

6.2.1
"If the declarator or type specifier that declares
the identifier appears inside a block or within the
list of parameter declarations in a function definition,
the identifier has block scope, which terminates at the
end of the associated block."

I believe this talks about what we learned early on :

int main(void)
{
{
int a;
}
printf("%d\n", a); /* ERROR - Invalid */
return 0;
}

Once outside of the closing } a is no longer accessible.
It's out of our current "scope". Which brings me to my
question. Since that data is static, is it automatically
allocated at program start up?

int main(void)
{
int i;
return 0;
}

As "i" would be in this example ? What if there's a conditional
statement there ? As in :

int main(void)
{
int i = 0;
if(!i) {
int a;
}
return 0;
}

If "a" is /NOT/ automatically allocated with "i", what is
the compiler doing to make sure it gets allocated only when,
and if it's ever needed (like if "i" changes before the
"if", or if it waits for input from a user which we'll assume
is unknown untill runtime will "a" still get allocated ?)

Any help is greatly appreciated, just something i started
wondering about :) FMorales...
 
P

Pushkar Pradhan

Did you try this?
In C you have to declare all variables first and then start your code.
So you would have to do
int a;
int i;

What you did is allowed in c++. I mean this code:
> int main(void)
> {
> int i = 0;
> if(!i) {
> int a;
> }
> return 0;
> }

Won't compile.
 
P

Paulo Pereira

Did you try this?
In C you have to declare all variables first and then start your code.

only in c89
in c99, variables can be declared anywhere.
So you would have to do
int a;
int i;

What you did is allowed in c++. I mean this code:

Won't compile.

any good compiler won't generate code for your conditional statement
unless you set i to be "volatile".

the compiler can't assume that unless you provide the keyword static
 
B

Bertrand Mollinier Toublet

Pushkar said:
Did you try this?
In C you have to declare all variables first and then start your code.
So you would have to do
int a;
int i;

What you did is allowed in c++. I mean this code:
Pushkar, you must have suffered a temporary access of madness. There is
nothing wrong with declaring variables at the beginning of a block. The
code above is perfectly valid C89 (as well as C99, of course).
 
A

Artie Gold

FMorales said:
-- I didn't notice anything about this specifically
-- in the c.l.c. FAQ, nor could i get a strait answere
-- from my copy of the C standard. Hopeing someone
-- here could shed some light on it :)...

6.2.1
"If the declarator or type specifier that declares
the identifier appears inside a block or within the
list of parameter declarations in a function definition,
the identifier has block scope, which terminates at the
end of the associated block."

I believe this talks about what we learned early on :

int main(void)
{
{
int a;
}
printf("%d\n", a); /* ERROR - Invalid */
return 0;
}

Once outside of the closing } a is no longer accessible.
It's out of our current "scope". Which brings me to my
Correct.

question. Since that data is static, is it automatically
allocated at program start up?

It's *not* static. It is an *automatic variable*.
int main(void)
{
int i;
return 0;
}

As "i" would be in this example ? What if there's a conditional
statement there ? As in :

int main(void)
{
int i = 0;
if(!i) {
int a;
}

`a' is now out of scope.
return 0;
}

If "a" is /NOT/ automatically allocated with "i", what is
the compiler doing to make sure it gets allocated only when,
and if it's ever needed (like if "i" changes before the
"if", or if it waits for input from a user which we'll assume
is unknown untill runtime will "a" still get allocated ?)

What a particular compiler does is irrelevant; it is free to do
whatever it wants as long as the program semantics are correct.
Any help is greatly appreciated, just something i started
wondering about :) FMorales...
Fair enough.

HTH,
--ag
 
P

Pushkar Pradhan

There is no need to get nasty, I tried it on my system and then only
sent my post. Somebody already pointed out I was wrong.
No need for you to show your frustration here.
 
B

Barry Schwarz

-- I didn't notice anything about this specifically
-- in the c.l.c. FAQ, nor could i get a strait answere
-- from my copy of the C standard. Hopeing someone
-- here could shed some light on it :)...

6.2.1
"If the declarator or type specifier that declares
the identifier appears inside a block or within the
list of parameter declarations in a function definition,
the identifier has block scope, which terminates at the
end of the associated block."

I believe this talks about what we learned early on :

int main(void)
{
{
int a;
}
printf("%d\n", a); /* ERROR - Invalid */
return 0;
}

Once outside of the closing } a is no longer accessible.
It's out of our current "scope". Which brings me to my
question. Since that data is static, is it automatically
allocated at program start up?

int main(void)
{
int i;
return 0;
}

As "i" would be in this example ? What if there's a conditional
statement there ? As in :

int main(void)
{
int i = 0;
if(!i) {
int a;
}
return 0;
}

If "a" is /NOT/ automatically allocated with "i", what is
the compiler doing to make sure it gets allocated only when,
and if it's ever needed (like if "i" changes before the
"if", or if it waits for input from a user which we'll assume
is unknown untill runtime will "a" still get allocated ?)

Any help is greatly appreciated, just something i started
wondering about :) FMorales...
You don't have any static objects in your sample code. While you
rethink the problem, consider that scope and duration (or life span)
have different meanings.


<<Remove the del for email>>
 
S

Sheldon Simms

There is no need to get nasty, I tried it on my system and then only
sent my post. Somebody already pointed out I was wrong.
No need for you to show your frustration here.

Are you claiming that the compiler you use on your system failed
to compile the code?
 
P

Pushkar Pradhan

Actually I did it without the block {}, that's why it failed. I mean
if(a)
int i;
 
P

Pushkar Pradhan

I think it is allocated at runtime, I used gdb on:
> int i = 0;
> if(!i) {
> int a;
> }
> return 0;
> }
When I tried to print a outside the loop gdb said:
No symbol "a" in current context
So it must have been created when the block is reached.
 
F

FMorales

Pushkar Pradhan said:
I think it is allocated at runtime, I used gdb on:
When I tried to print a outside the loop gdb said:
No symbol "a" in current context
So it must have been created when the block is reached.

See now that to me makes sense. Since "a" is only valid inside
that block of code, i wouldn't be able to read it outside. My
only question would be this :

Just because "a" is not readable outside that scope, does that
mean "a" hasn't already been allocated ? So would there already
be memory set aside for an integer variable named "a", but
because of the rules in the C language it's simply not accessible,
untill inside that block of code ? OR if there's a situation like the
one i presented where there's a posibility that block of code may
infact never be reached, would allocating "a" be based on if that
condition is true, and i enter the block of code ? (Thus at program
startup there is no space for an integer variable named "a". But
rather when my condition is met, and i enter the block of code
where "a" is valid, THEN and only then does my program
"dynamically" (i use this with caution, as i'm not using any standard
library functions, malloc\calloc\realloc, etc.. but it's created 'on the
fly'. If that proves to be the case) create space for an integer
named "a" for use inside that block of code. Which i assume would
be 'free'ed after that block of code...) Example :

int main(void)
{
int i = 1; /* When my program starts it would have allocated room
* for an integer variable with the name "i"
*/
if(!i) {
int a; /* Now the only place in this code "a" is valid is inside
this
* if statement. However you can clearly see it will infact
* be evaluated to 'false' thus anything inside the block of
* code will never be reached. So would memory for "a" have
* been set aside /anyways/ ? Thus i have 2 places in memory
* allocated for 2 integers, one with the name "i" one with
"a",
* when my program starts up ? OR would there be space for
* only "i" and "if(!i)" ever evaluates true, then and only
then will
* space be allocated for "a". For use only inside this code
block.
*/
}
return 0;
}

Also i apologize for not being more specific, when i used the term
'static', i didn't mean to imply : static int a; , which i seemed to have
done. I mean data that's not dynamically allocated via, malloc\calloc\
realloc, etc... That's the term i've used "statically allocated" as apposed
to "dynamically", but i can see how just static caused confusion.

Again appreciate any comments, and or questions... Thx again all,
FMorales
 
C

Chris Torek

[Background: we are given code like:

void f(void) {
...
if (some_expression) {
int a;
...
}
...
}

inside a function.]

Just because "a" is not readable outside that scope, does that
mean "a" hasn't already been allocated ?

In a conforming C program -- that is, one that obeys the rules of
the C standards, and does not use undefined behavior -- what code
would you write to detect whether or not memory for that object
has been allocated?

If it is impossible to write such code, *any* C compiler is free
to *change* the actual code in any way that you cannot detect. In
other words, wherever there is no way to tell precisely when a
variable is allocated, the compiler is allowed to allocate it (or
not allocate it) at any time.

I will tell you that it *is* impossible to write conforming code
that discovers precisely when "a" is allocated. (You get to decide
whether you believe me. :) ) Thus, the compiler is free to allocate
space for the variable "a" upon entering function f(), or to defer
allocating space for the variable "a" until entering the block
containing "a". There are, in the general case, valid arguments
for doing it *both* ways, so some compilers choose one way, and
some choose the other.

Any time you write code in C (instead of, e.g., assembly), you give
up some degree of control. If you were writing x86 assembly, *you*
could choose whether to place "a" in a stack frame, and if so, when
to adjust the %esp register -- but if you use a C compiler, you
give up that ability. Your C compiler chooses where to place "a"
and when to allocate any such storage. Unless you are willing to
pin yourself down to one specific version of one specific compiler
(and target machine), under one specific set of optimization flags
and the like, you cannot predict exactly what it will do. But for
ordinary C code, you should not care; and you should not *need* to
care. As long as you obey your part of the "ANSI C contract" --
the restrictions the C standard places on you as a programmer --
you should be able to depend on your compiler obeying its part, of
generating code that does what that standard requires.

Sometimes, of course, you will find that you need something that
Standard C simply does not provide. In this case, you must rely
on some sort of additional guarantees, such as those in an additional
standard (e.g., some POSIX standard) or those from some compiler
vendor. It seems unlikely that you will find many (if any) guarantees
about when a variable like "a" is allocated, though. Luckily, it
is equally unlikley to matter in practice.
 
M

Micah Cowan

Pushkar Pradhan said:
Did you try this?
In C you have to declare all variables first and then start your code.
So you would have to do
int a;
int i;

What you did is allowed in c++. I mean this code:

Won't compile.

Really? Did you try?

Compound statements have always allowed declarations (at the
top), even in C90. "int a" is clearly within a compound
statement. No problem.

-Micah
 
M

Micah Cowan

FMorales said:
6.2.1
"If the declarator or type specifier that declares
the identifier appears inside a block or within the
list of parameter declarations in a function definition,
the identifier has block scope, which terminates at the
end of the associated block."

I believe this talks about what we learned early on :

int main(void)
{
{
int a;
}
printf("%d\n", a); /* ERROR - Invalid */
return 0;
}

Once outside of the closing } a is no longer accessible.
It's out of our current "scope". Which brings me to my
question. Since that data is static, is it automatically
allocated at program start up?

That data is *not* static, it is automatic. How it is allocated
is not really important, but since main could be called
recursively, it would probably be allocated as it is encountered
(actually, any smart compiler wouldn't allocate it at all, seeing
that it's never used before its scope ends).
int main(void)
{
int i;
return 0;
}

As "i" would be in this example ? What if there's a conditional
statement there ? As in :

int main(void)
{
int i = 0;
if(!i) {
int a;
}
return 0;
}

If "a" is /NOT/ automatically allocated with "i", what is
the compiler doing to make sure it gets allocated only when,
and if it's ever needed (like if "i" changes before the
"if", or if it waits for input from a user which we'll assume
is unknown untill runtime will "a" still get allocated ?)

A compiler is perfectly fine to allcoate it along with i or not:
it just won't let you refer to it unless you're within the if
statement block.

-Micah
 
J

James Hu

[Background: we are given code like:

void f(void) {
...
if (some_expression) {
int a;
...
}
...
}

inside a function.]

Just because "a" is not readable outside that scope, does that
mean "a" hasn't already been allocated ?
[...]

I will tell you that it *is* impossible to write conforming code that
discovers precisely when "a" is allocated. (You get to decide whether
you believe me. :) )

(Since the only requirement of a conforming program is that it be
acceptable by a conforming implementation, it would be unwise to
bet against this.)
Thus, the compiler is free to allocate space for
the variable "a" upon entering function f(), or to defer allocating
space for the variable "a" until entering the block containing "a".
There are, in the general case, valid arguments for doing it *both*
ways, so some compilers choose one way, and some choose the other.

In addition, consider the case when the function includes multiple
blocks with their own automatic variables:

void f(void) {
...
if (some_expression) {
int a;
...
}
...
if (some_other_expression) {
int b;
...
}
...
}

Then "a" and "b" may occupy the same allocated space, irrespective of
when the space is allocated.

-- James
 
E

Emmanuel Delahaye

FMorales said:
6.2.1
"If the declarator or type specifier that declares
the identifier appears inside a block or within the
list of parameter declarations in a function definition,
the identifier has block scope, which terminates at the
end of the associated block."

I believe this talks about what we learned early on :

int main(void)
{
{
int a;
}
printf("%d\n", a); /* ERROR - Invalid */

Yes. The 'a' identifier is not in scope.
return 0;
}

Once outside of the closing } a is no longer accessible.
It's out of our current "scope". Which brings me to my
question. Since that data is static, is it automatically
allocated at program start up?

If you mean 'If a data is defined static', yes, it is somehow 'allocated' at
startup. It's also set to a valid 0 value.
int main(void)
{
int i;
return 0;
}

As "i" would be in this example ?

'i' is not defined 'static'. It's an automatic variable, and it's not
initialized at all.
What if there's a conditional
statement there ? As in :
int main(void)
{
int i = 0;
if(!i) {
int a;
}
return 0;
}

If "a" is /NOT/ automatically allocated with "i", what is
the compiler doing to make sure it gets allocated only when,
and if it's ever needed (like if "i" changes before the
"if", or if it waits for input from a user which we'll assume
is unknown untill runtime will "a" still get allocated ?)

The actual detailed way of the data is allocated is irrelevent. All we need
to know is that the scope is limited to the block where it is defined.

This code is invalid:

int main (void)
{
int *p = NULL;
int a = 2;

if (a > 1)
{
int x;
p = &x;
}

*p = 123; /* UB: the value of the pointer is no longer valid. */

return 0;
}
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
Did you try this?

Did you?
In C you have to declare all variables first and then start your code.

Wrong. In C90, they must be defined a the top of a bloc. In C99, anywhere.
So you would have to do
int a;
int i;

You can, but you don't /have to/
What you did is allowed in c++. I mean this code:

What the heck is C++?
Won't compile.

Wrong. Try it yourself.

main.c: In function `main':
main.c:5: warning: unused variable `a'


Please check your skills before posting. I suggest you re-read the Kernighan
and Ritchie ed.2. It won't hurt.
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
Actually I did it without the block {}, that's why it failed. I mean
if(a)
int i;

Of course, if you changed the code... The C language (C90) says 'at the the
top of a block'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top