473,765 Members | 2,005 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

allocation of local variables on stack

Hi,

When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations? Is a function activation record supposed to be
fixed before you start executing the function code (i.e. statements)?

If this is done at run-time, how does the (standard) compiler do it?

I have also heard about an alloca() call for allocating on the stack.
Is this a non-standard function? Is there a possibility of stack
overflow by doing this?

Thanks,
Bahadir

Nov 14 '05 #1
26 2880


ba************@ gmail.com wrote:
Hi,

When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations?
They are allocated whenever (and wherever) the compiler
chooses. Different compilers will use different strategies;
a single compiler may use different strategies depending on
the rest of the code.
Is a function activation record supposed to be
fixed before you start executing the function code (i.e. statements)?
C does not have a "function activation record." While
a function is executing there is enough information stored
somewhere to allow it to return to its caller and perhaps to
return a value, but that's about all one can say. Again, it's
the compiler's choice about how to maintain this information,
and different compilers will do it differently.
If this is done at run-time, how does the (standard) compiler do it?
I'm not sure what you're asking -- but in any case, there
is no one standard compiler, no "reference implementation. " The
language definition describes the effect of running a valid program,
but not how that effect is achieved. Almost all such matters are
left to the discretion of the implementors, so they can have the
freedom to exploit the special characteristics of the platform.
I have also heard about an alloca() call for allocating on the stack.
Is this a non-standard function? Is there a possibility of stack
overflow by doing this?


See Question 7.32 in the comp.lang.c Frequently Asked
Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

--
Er*********@sun .com

Nov 14 '05 #2
In article <11************ **********@g44g 2000cwa.googleg roups.com>,
<ba************ @gmail.com> wrote:

When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations?


It's better to program as if you didn't know or care, and in
a lot of cases simple variables like that won't even be
on the stack. They'll be optimized away or placed in registers.

With that out of the way, in my observations of a several
different machines, the stack is usually allocated all-at-once
upon entry to the function. There can be overlap though:

void func()
{
int a;

{
int b;
}
{
int c;
}
}

b and c may share a memory location, and that shared b+c memory
location is probably "allocated" on the "stack" at the same
time as a. I use scare quotes because these are implementation-specific
concepts that aren't part of C proper.

About the only time I think any of these issues would be
externally visible would be if a recursive function
used an excessive amount of stack space in a nested
statement, but the recursion occured outside of that.
Consider this incomplete code:

int func(int a)
{
if (a > 0)
{
/* non-trivial return (usually) prevents tail-recursion elimination */
return other_func(a) * func(a-1);
}
else
{
struct gigantic_struct foo[1000000];
/* perform non-trivial processing of gigantic struct array */
/* return non-trivial value after processing */
}
}

Unless the compiler was particularly clever, it might grow
the stack at an alarming rate. I'll have to try this
one out with my favorite compilers and see what happens.
--
7842++
Nov 14 '05 #3
Anonymous 7843 wrote:
In article <11************ **********@g44g 2000cwa.googleg roups.com>,
<ba************ @gmail.com> wrote:

When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations?


It's better to program as if you didn't know or care, and in
a lot of cases simple variables like that won't even be
on the stack. They'll be optimized away or placed in registers.

With that out of the way, in my observations of a several
different machines, the stack is usually allocated all-at-once
upon entry to the function. There can be overlap though:

void func()
{
int a;

{
int b;
}
{
int c;
}
}

b and c may share a memory location, and that shared b+c memory
location is probably "allocated" on the "stack" at the same
time as a. I use scare quotes because these are implementation-specific
concepts that aren't part of C proper.

About the only time I think any of these issues would be
externally visible would be if a recursive function
used an excessive amount of stack space in a nested
statement, but the recursion occured outside of that.
Consider this incomplete code:

int func(int a)
{
if (a > 0)
{
/* non-trivial return (usually) prevents tail-recursion elimination */
return other_func(a) * func(a-1);
}
else
{
struct gigantic_struct foo[1000000];
/* perform non-trivial processing of gigantic struct array */
/* return non-trivial value after processing */
}
}

Unless the compiler was particularly clever, it might grow
the stack at an alarming rate. I'll have to try this
one out with my favorite compilers and see what happens.
--
7842++


Thanks a lot, your explanation was very helpful. I asked this because I
was also wondering what would happen when a similar situation as you
exemplified would occur. But yours emphasised it better.

I personally care for these things even if you save an array or two at
runtime. It doesn't make a big difference but it doesn't hurt to code
knowing about it. It may even help in limited stack situations.

Thanks,
Bahadir

Nov 14 '05 #4

Le 14/06/2005 18:51, dans
11************* *********@g44g2 00...legr oups.com,
«*ba*********** *@gmail.com*» <ba************ @gmail.com> a écrit*:
Hi,

When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations? Is a function activation record supposed to be
fixed before you start executing the function code (i.e. statements)?
As already stated, it's implementation dependent. On MacOSX/PowerPC, the
stack is fixed at the beginning of the function, and is not easily
changed afterwards: there is a 24 byte block at the end of the stack frame,
used by any called function. I haven't checked but probably alloca needs to
change this block. On Wintel on the other hand, the stack may be expanded
at any time.

Another interesting point (MacOSX): when a function is called, parameters
are passed by register and if needed on the caller's stack frame, so when
a function is entered, enough space must be reserved in its stack frame
for any function it calls, even if it actually don't call any: the compiler
cannot know that. And of course the stack frame must contain space for
all local variables. This makes a rather big stack frame :-)

If this is done at run-time, how does the (standard) compiler do it?

I have also heard about an alloca() call for allocating on the stack.
Is this a non-standard function? Is there a possibility of stack
overflow by doing this?

Thanks,
Bahadir


Nov 14 '05 #5
ba************@ gmail.com wrote:
Anonymous 7843 wrote:
<ba************ @gmail.com> wrote:

When you define varibles in the middle of your function call
(C99), such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at
run-time or are they allocated before, along with the
arguments and initial variable declarations?
It's better to program as if you didn't know or care, and in
a lot of cases simple variables like that won't even be
on the stack. They'll be optimized away or placed in registers.

With that out of the way, in my observations of a several
different machines, the stack is usually allocated all-at-once
upon entry to the function. There can be overlap though:

void func() { /* EDITED for compression cbf */
int a;
{ int b; }
{ int c; }
}

b and c may share a memory location, and that shared b+c memory
location is probably "allocated" on the "stack" at the same
time as a. I use scare quotes because these are implementation-
specific concepts that aren't part of C proper.

.... snip ...
Thanks a lot, your explanation was very helpful. I asked this
because I was also wondering what would happen when a similar
situation as you exemplified would occur. But yours emphasised it
better.

I personally care for these things even if you save an array or
two at runtime. It doesn't make a big difference but it doesn't
hurt to code knowing about it. It may even help in limited stack
situations.


I'm leaping in here for two reasons. One is that you are a google
user who is using the system correctly, with adequate quotes etc.
So it IS possible. Congratulations , and it shows that we should
not automatically killfile all google users.

The other is the generic problem of off-topicness. This whole
thread is off-topic, yet where is the newbie to go? [1] We who
have been around for <mumble> [2] years have a pretty good idea of
how things are implemented, or have done the implementation. As a
result we have a fair idea of why the standard imposes, or doesn't
impose, things in various areas. This knowledge is not system or
language or machine specific until it is applied to one specific
situation. One example is stacks. The IBM 360 family doesn't have
them. Yet it can implement automatic storage. Almost everything
that grew out of the PDP11, VAX, x86, 68xxx, etc. has stack
capabilities.

There was a time when all programming, to all practical purposes,
was done in assembly. As languages and their implementations
improved assembly grew less and less important, EXCEPT to the
implementors. Nowadays we can even restrict that EXCEPT to the
implementors of the final code generators. But the assembly
features are built to facilitate the high level language
implementation, and the implementations are skewed to use the
existing machine features, etc. There is no really sharp
demarcation point. We're here because there's beer because we're
here.

I've been around here for a while, so I'll probably get away with
this without excessive bitching. You, on the other hand, would
most likely have been yelled at for a similar post. And that may
be quite proper, in that I think I have demonstrated that I have a
fairly good idea of what I am talking about, and you haven't. As
yet. In time, you may.

[1] Not comp.programmin g, that deals with algorithms etc. Not
comp.os.*, those deal with particular systems. Not
comp.compilers. *, because the users need the knowledge. We need
comp.misc. Maybe it exists? But even if it does, it probably
doesn't have much traffic.

[2] <grumble>

--
"If you want to post a followup via groups.google.c om, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #6
Anonymous 7843 wrote:
In article <11************ **********@g44g 2000cwa.googleg roups.com>,
<ba************ @gmail.com> wrote:
When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations?

It's better to program as if you didn't know or care, and in
a lot of cases simple variables like that won't even be
on the stack. They'll be optimized away or placed in registers.

With that out of the way, in my observations of a several
different machines, the stack is usually allocated all-at-once
upon entry to the function. There can be overlap though:

void func()
{
int a;

{
int b;
}
{
int c;
}
}

b and c may share a memory location, and that shared b+c memory
location is probably "allocated" on the "stack" at the same
time as a. I use scare quotes because these are implementation-specific
concepts that aren't part of C proper.

About the only time I think any of these issues would be
externally visible would be if a recursive function
used an excessive amount of stack space in a nested
statement, but the recursion occured outside of that.
Consider this incomplete code:

....

Sometimes you don't know how much data you're going to read, so you
just have to plonk stuff on the stack regardless:

char* getfile(FILE *infile)
{
size_t i = 0;
char myarray[0];

while(!feof(inf ile)) {
myarray[i++] = fgetc(infile);
}

alloca(i);

char *buf = malloc(i);
memcpy(buf, myarray, i);
return buf;
}

Portability is all well and good, but i just wouldn't want to use a machine
that has no storage as easy to use as a stack. Without the stack, you'd have
to use expensive reallocs.
Nov 14 '05 #7
Russell Shaw wrote:
Anonymous 7843 wrote:
In article <11************ **********@g44g 2000cwa.googleg roups.com>,
<ba************ @gmail.com> wrote:
When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations?
It's better to program as if you didn't know or care, and in
a lot of cases simple variables like that won't even be
on the stack. They'll be optimized away or placed in registers.

With that out of the way, in my observations of a several
different machines, the stack is usually allocated all-at-once upon
entry to the function. There can be overlap though:

void func()
{
int a;
{
int b;
}
{
int c;
}
}

b and c may share a memory location, and that shared b+c memory
location is probably "allocated" on the "stack" at the same
time as a. I use scare quotes because these are implementation-specific
concepts that aren't part of C proper.

About the only time I think any of these issues would be
externally visible would be if a recursive function
used an excessive amount of stack space in a nested
statement, but the recursion occured outside of that.
Consider this incomplete code:


...

Sometimes you don't know how much data you're going to read, so you
just have to plonk stuff on the stack regardless:

char* getfile(FILE *infile)
{
size_t i = 0;
char myarray[0];

while(!feof(inf ile)) {
myarray[i++] = fgetc(infile);
}

alloca(i);

char *buf = malloc(i);


Correction:
memcpy(buf, myarray, i);
memcpy(buf, myarray + i + 1, myarray);
return buf;
}

Portability is all well and good, but i just wouldn't want to use a machine
that has no storage as easy to use as a stack. Without the stack, you'd
have
to use expensive reallocs.

Nov 14 '05 #8
Russell Shaw wrote:
Anonymous 7843 wrote:
In article <11************ **********@g44g 2000cwa.googleg roups.com>,
<ba************ @gmail.com> wrote:
When you define varibles in the middle of your function call (C99),
such as:

if(i == 5) {
int x = 5;
int z = 2;
}

Are they allocated on the stack as they're encountered at run-time or
are they allocated before, along with the arguments and initial
variable declarations?
It's better to program as if you didn't know or care, and in
a lot of cases simple variables like that won't even be
on the stack. They'll be optimized away or placed in registers.

With that out of the way, in my observations of a several
different machines, the stack is usually allocated all-at-once upon
entry to the function. There can be overlap though:

void func()
{
int a;
{
int b;
}
{
int c;
}
}

b and c may share a memory location, and that shared b+c memory
location is probably "allocated" on the "stack" at the same
time as a. I use scare quotes because these are implementation-specific
concepts that aren't part of C proper.

About the only time I think any of these issues would be
externally visible would be if a recursive function
used an excessive amount of stack space in a nested
statement, but the recursion occured outside of that.
Consider this incomplete code:


...

Sometimes you don't know how much data you're going to read, so you
just have to plonk stuff on the stack regardless:

char* getfile(FILE *infile)
{
size_t i = 0;
char myarray[0];

while(!feof(inf ile)) {
myarray[i++] = fgetc(infile);
}

alloca(i);

char *buf = malloc(i);


Correction(2):
memcpy(buf, myarray, i);
memcpy(buf, myarray + i + 1, i);
return buf;
}

Portability is all well and good, but i just wouldn't want to use a machine
that has no storage as easy to use as a stack. Without the stack, you'd
have
to use expensive reallocs.

Nov 14 '05 #9
Russell Shaw <rjshawN_o@s_pa m.netspace.net. au> writes:
[...]
Sometimes you don't know how much data you're going to read, so you
just have to plonk stuff on the stack regardless:

char* getfile(FILE *infile)
{
size_t i = 0;
char myarray[0];

while(!feof(inf ile)) {
myarray[i++] = fgetc(infile);
}

alloca(i);

char *buf = malloc(i);
memcpy(buf, myarray, i);
return buf;
}

Portability is all well and good, but i just wouldn't want to use a machine
that has no storage as easy to use as a stack. Without the stack, you'd have
to use expensive reallocs.


Sorry, but that's just ugly. Apart from the misuse of feof() (you
should be checking whether fgetc() returned EOF), and the constraint
violation of declaring a zero-length array, you're assuming that the
space beyond myarray is "above" the top of the stack. Even assuming a
stack-based implementation, I can imagine the unallocated space you're
using being clobbered by an interrupt. (I don't even want to think
about what might happen in a multi-threading environment.)

There are functions available that will read a line of arbitrary
length from an input file, allocating it on the heap and expanding
with realloc() as necessary. If can be done portably, there's no
need, and no excuse, for code like the above.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
8213
by: chris | last post by:
Hi all, I need to know, what is the difference between dynamic memory allocation, and stack allocation ? 1. If I have a class named DestinationAddress, when should I use dynamic memory allocation to create object of that class ? 2. If it says "dynamic memory allocation", is it mean the following code : DestinationAddress* dest = new DestinationAddress(); // code 1
3
3339
by: asm | last post by:
Hello all, I need your help on this problem. I wrote a little program as follows. (BTW, I worked on a new dell latitude, runing Linux kernel 2.4.19, i686). Program was compiled with gcc 3.2 void foo() { char t; strcpy(t, "012345678901234567890123456789012345678");
34
2176
by: FMorales | last post by:
-- 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
4
7236
by: gamja | last post by:
Hi all. I know that some padding bits are inserted between data members of a structure. Is this rule also applied for the variables on local stack or global??? For example, in following code dumps... ------------ struct foo foo1; .... struct bar bar1;
4
6629
by: veera sekhar kota | last post by:
I read structs are stored at stack area or inline-heap based objects. What is meant by inline-heap based objects? I didnt get that. Thanks, Veera.
2
2321
by: sandy | last post by:
Hi all, I tried compiling the above two programs : on x86, 32 bit machines. And when I used objdump on that I saw the following code. Can anyone help me know, Why in the objdump of our first program the esp is decremented by 18H bytes and in the second program the esp is decremented by 28H bytes.
53
26393
by: fdmfdmfdm | last post by:
This is an interview question and I gave out my answer here, could you please check for me? Q. What are the memory allocation for static variable in a function, an automatic variable and global variable? My answer: static variable in function and global variable are allocated in head, and automatic variable is allocated in stack. Right?
14
3835
by: vivek | last post by:
i have some doubts on dynamic memory allocation and stacks and heaps where is the dynamic memory allocation used? in function calls there are some counters like "i" in the below function. Is this stored in stack. If yes whether it will be deleted on exiting from the function. is dynamic memory allocation needed for this purpose
5
1565
by: peridian | last post by:
Hello, I may be remembering incorrectly, but I'm sure that in C++ you could declare two variables of the same name where the second declaration is within it's own code block. E.g. void myfunction() { int x = 5; //some code
0
9568
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9835
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8833
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7379
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5277
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3926
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3532
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2806
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.