Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Variables allocated on stack

Reply
Thread Tools

Variables allocated on stack

 
 
Seebs
Guest
Posts: n/a
 
      11-26-2011
On 2011-11-24, Bogdan <(E-Mail Removed)> wrote:
> I had during an interview this question: which variables are
> allocated on the stack in a function?


That is a very poor question for an interviewer to use.

> I am unsure how the output
> variable is handled. Is this one too allocated on the stack and popped
> when the function exists ?


Maybe. Often, the answer is "no".

> char* some_function(char c)
> {
> char *out = malloc(10);
> return out;
> }


> On the local stack are there one char and 2 pointers to chars ?


There may or may not be a "local stack" in any meaningful sense. Since
we know that this function is functionally a leaf node (it never calls
anything that could possibly recurse to it), it would be quite reasonable
for a compiler to use a calling convention based on register values.
Since some ABIs use registers by convention for return values, and the
argument is ignored, the function might well consist entirely of shoving
an immediate 10 into a register and calling malloc, which would stash its
return value in the same register this function would have used, and then
there's nothing more to do.

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / http://www.velocityreviews.com/forums/(E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
 
 
 
Bogdan
Guest
Posts: n/a
 
      11-26-2011
On Nov 25, 10:53*am, Malcolm McLean <(E-Mail Removed)>
wrote:
> On Nov 24, 11:28*pm, Bogdan <(E-Mail Removed)> wrote:
>
>
>
>
>
>
>
> > Hi

>
> > *I had during an interview this question: which variables are
> > allocated on the stack in a function ? I am unsure how the output
> > variable is handled. Is this one too allocated on the stack and popped
> > when the function exists ?
> > Here is an example:

>
> > char* some_function(char c)
> > {
> > * * *char *out = malloc(10);
> > * * *return out;

>
> > }

>
> > On the local stack are there one char and 2 pointers to chars ?

>
> A modern compiler would probably just optimise that function to a call
> to malloc().
>
> However the abstract C compiler needs a stack for the function calls,
> and a stack for variables. When you call a function, the address of
> the instruction to return to in caller is pushed onto the call stack.
> Then the parameters are pushed onto the variable stack (in this case,
> c). Then the local variables are pushed onto the variable stack (in
> this case, out). The function then does its calculations, the variable
> stack is popped, the return address is popped off the call stack and
> the function returns. So what happens to the return value? Almost
> always, it is returned in a register.
>
> However pushing and popping stacks is not very efficient. So compilers
> use registers as much as possible. On most processors, the first four
> parameters will be passed in registers. Also, the call stack can be
> the same as the variable stack.
> --
> New: sequence logo generatorhttp://www.maclommclean.site11.com/www



I guess that it depends on the output variable size. When we need to
return a structure I guess that the variable stack should be always
used.
 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      11-26-2011
"Seebs" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 2011-11-25, BartC <(E-Mail Removed)> wrote:


>> fn(f(p,q,r), g(s), h(t,u,v), i());

>
>> Here, purely stack-based parameters would be far simpler.

>
> Right.
>
> But you don't always get a vote -- the ABI may have specified the rules
> for you. And in fact, often has.


Surely compiler writers can do what they like - within their own
implementation? Calling conventions are only important when calling foreign
and OS functions, and being called from outside.

--
Bartc

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      11-26-2011
On 11/26/2011 4:18 AM, Bogdan wrote:
>[... function linkage mechanisms ...]
>
> I guess that it depends on the output variable size. When we need to
> return a structure I guess that the variable stack should be always
> used.


On one compiler I've used, struct-valued functions were handled
rather differently. The function was rewritten like a void function
with an extra, invisible argument pointing to a temporary struct that
would receive the value. That is, you'd write

struct foo func(int bar) {
struct foo result;
...
return result;
}

struct foo baz = func(42);

.... and the compiler would rewrite to something like

void func(struct foo* _output, int bar) {
struct foo result;
...
*_output = result;
}

struct foo _temp;
struct foo baz;
func(&_temp, 42);
baz = _temp;

(Why use _temp instead of just func(&baz, 42)? Because the
compiler had to guard against the possibility that func() might
use baz directly -- as a global, say, or via another pointer.)

The lesson here is that words like "always" are risky in this
connection. Platforms differ, and present implementors with
differing challenges, and those challenges are met with different
strategies. This is probably why the Standard says so very little
about such matters: To give the implementors maximum freedom to
exploit the strengths and avoid the weaknesses of the platforms.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
Markus Wichmann
Guest
Posts: n/a
 
      11-26-2011
On 26.11.2011 12:07, BartC wrote:

> Surely compiler writers can do what they like - within their own
> implementation? Calling conventions are only important when calling foreign
> and OS functions, and being called from outside.
>


Yeah, that's right!

Only... every function not defined "static" may be called "from the
outside". Every call to a function only declared (and not qualified
"static") but not defined may be to a foreign function.

Plus, when you ask a compiler writer whether he want's to include
_two_different_ calling conventions in his compiler with the added
maintenance and stuff, guess what he'll say. Writing a register
allocator is hard enough without having to differentiate internal and
external functions and function calls.

CYA,
Markus
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      11-26-2011


"Markus Wichmann" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 26.11.2011 12:07, BartC wrote:
>
>> Surely compiler writers can do what they like - within their own
>> implementation? Calling conventions are only important when calling
>> foreign
>> and OS functions, and being called from outside.
>>

>
> Yeah, that's right!
>
> Only... every function not defined "static" may be called "from the
> outside". Every call to a function only declared (and not qualified
> "static") but not defined may be to a foreign function.


If no special attributes are defined, then it is just the private calling
convention used by this compiler. Although it might have a few other
conventions up it's sleeve, for example when creating exported functions
accessed via dynamic library by other languages, or calling the OS.

I'm used anyway to declaring in my non-C language:

clang function puts (istring)
windows function Sleep(int)

That is, specify the calling conventions used by these imported functions
(in this case, also imported via DLL files). Although I believe Windows was
originally written in C, it uses a different call convention from actual C
programs.

Fortunately the only C functions I've had to import so far all use a
consistent call convention. So for functions shared across applications,
this would be a good idea. But should this be defined by the ABI? I
understood an ABI was mainly for interfacing to the OS; it was not
necessarily a standard for C language compilers. Or, since other languages
are available, for *every* implementation of *every* language for that
platform.

> Plus, when you ask a compiler writer whether he want's to include
> _two_different_ calling conventions in his compiler with the added
> maintenance and stuff, guess what he'll say.


Isn't that what happens anyway, when calling a function in a different
language? (pascal, stdcall and so on.) (And I'm working right now on a
project with I think 4 different conventions to take care of. It's not that
big a deal. More difficult is matching and converting datatypes across
languages.)

> Writing a register
> allocator is hard enough without having to differentiate internal and
> external functions and function calls.


Most code generation should be for functions following the chosen
call-convention of the compiler. This may well have been chosen to be easier
to compile for. Only actual calls to other conventions, or 'callback'
functions, might need some work.

--
Bartc

 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      11-26-2011
On 11/27/11 12:00 PM, BartC wrote:
> "Markus Wichmann"<(E-Mail Removed)> wrote:
>
>> Plus, when you ask a compiler writer whether he want's to include
>> _two_different_ calling conventions in his compiler with the added
>> maintenance and stuff, guess what he'll say.

>
> Isn't that what happens anyway, when calling a function in a different
> language? (pascal, stdcall and so on.)


No. At least not on any of the platforms I'm familiar with. Other
languages know how to call C (so they can access the platform's services).

> (And I'm working right now on a
> project with I think 4 different conventions to take care of. It's not that
> big a deal. More difficult is matching and converting datatypes across
> languages.)


Yet again the convention is to describe those structures in C calling ABI.

--
Ian Collins
 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      11-26-2011
Ian Collins <(E-Mail Removed)> writes:
>No. At least not on any of the platforms I'm familiar with. Other
>languages know how to call C (so they can access the platform's services).


In this case, wouldn't »know how to call the platform's ABI«
a more appropriate wording than »know how to call C«?

 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      11-26-2011
"Ian Collins" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 11/27/11 12:00 PM, BartC wrote:
>> "Markus Wichmann"<(E-Mail Removed)> wrote:
>>
>>> Plus, when you ask a compiler writer whether he want's to include
>>> _two_different_ calling conventions in his compiler with the added
>>> maintenance and stuff, guess what he'll say.

>>
>> Isn't that what happens anyway, when calling a function in a different
>> language? (pascal, stdcall and so on.)

>
> No. At least not on any of the platforms I'm familiar with.


So how do you call Pascal, Fortran, (or C++) etc from C on your platform? Do
you not need to tell it that that imported function is in a different
language?

> Other languages know how to call C (so they can access the platform's
> services).


The platform interface should be language-independent. This is where a
binary interface becomes useful. (C has done a good job here in past, in
defining such interfaces, but there is often confusion; is 'long' 32-bits or
64-bits for example? gcc for Windows says 32, gcc for Linux says 64.)

But should a complex, register-based interface (I believe this might be for
x86-64) be also used as the standard when one C function calls another C
function in the same application?

--
Bartc

 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      11-26-2011
On 11/27/11 12:35 PM, BartC wrote:
> "Ian Collins"<(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> On 11/27/11 12:00 PM, BartC wrote:
>>> "Markus Wichmann"<(E-Mail Removed)> wrote:
>>>
>>>> Plus, when you ask a compiler writer whether he want's to include
>>>> _two_different_ calling conventions in his compiler with the added
>>>> maintenance and stuff, guess what he'll say.
>>>
>>> Isn't that what happens anyway, when calling a function in a different
>>> language? (pascal, stdcall and so on.)

>>
>> No. At least not on any of the platforms I'm familiar with.

>
> So how do you call Pascal, Fortran, (or C++) etc from C on your platform? Do
> you not need to tell it that that imported function is in a different
> language?


Fortran and C++ have standard mechanisms for C interoperability. I
don't know about Pascal, I haven't used it since the 80s...

>> Other languages know how to call C (so they can access the platform's
>> services).

>
> The platform interface should be language-independent. This is where a
> binary interface becomes useful. (C has done a good job here in past, in
> defining such interfaces, but there is often confusion; is 'long' 32-bits or
> 64-bits for example? gcc for Windows says 32, gcc for Linux says 64.)


The sizes of types is defined by the platform's ABI. When in Rome and
all that..

> But should a complex, register-based interface (I believe this might be for
> x86-64) be also used as the standard when one C function calls another C
> function in the same application?


Why not? The AMD64 calling convention offers significant performance
advantages.

--
Ian Collins
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C/C++ compilers have one stack for local variables and return addresses and then another stack for array allocations on the stack. Casey Hawthorne C Programming 3 11-01-2009 08:23 PM
stack frame size on linux/solaris of a running application stack Surinder Singh C Programming 1 12-20-2007 01:16 PM
perl variables allocated in shared memory - feasible/possible/done already? Chris Perl Misc 1 02-03-2007 06:12 PM
variable allocated from stack/bss ?? onkar C Programming 148 12-18-2006 07:22 AM
Dynamically Allocated Memory vs. Statically allocated Memory csnerd@gmail.com C++ 5 12-09-2004 01:44 AM



Advertisments