Thread: Looping & stacks

  1. #1
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591

    Looping & stacks

    When creating a variable used within a loop, is it quicker/more effecient to redefine the variable every loop repetition or define it once in a higher scope? I.E.:
    Code:
    while(p != NULL)
    {
      char buf[BUFSIZ];
      strcpy(buf, p->str);
    }
    vs.
    Code:
    char buf[BUFSIZ];
    while(p != NULL)
    {
       strcpy(buf, p->str);
    }
    So in the former, buf is being redefined every iteration, which may maximize the use of space, but in the latter, time is not wasted setting up space again and again (however, buf must still at least be passed on the stack, right?). So I'm wondering if there really is a space/speed tradeoff between the two? Which is faster? more effecient? Or does it even really matter if you have an optimizing compiler (i.e. gcc (-O3))?

  2. #2
    Registered User
    Join Date
    May 2007
    Posts
    58
    So in the former, buf is being redefined every iteration, which may maximize the use of space
    I didn't get that.


    I think that the best would be the second one.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int i;
    	for(i=0;i<100;i++)
    	{
    		char szBuffer[1000];
    		strcpy(szBuffer,"bleh");
    		printf("szBuffer = &#37;s\n",szBuffer);
    	}
    	return 0;
    }
    Code:
            .file   "tehlocal.c"
            .def    ___main;        .scl    2;      .type   32;     .endef
            .section .rdata,"dr"
    LC0:
            .ascii "bleh\0"
    LC1:
            .ascii "szBuffer = %s\12\0"
            .text
    .globl _main
            .def    _main;  .scl    2;      .type   32;     .endef
    _main:
            pushl   %ebp
            movl    %esp, %ebp
            subl    $1064, %esp
            andl    $-16, %esp
            movl    $0, %eax
            addl    $15, %eax
            addl    $15, %eax
            shrl    $4, %eax
            sall    $4, %eax
            movl    %eax, -1036(%ebp)
            movl    -1036(%ebp), %eax
            call    __alloca
            call    ___main
            movl    $0, -12(%ebp)
    L2:
            cmpl    $99, -12(%ebp)
            jg      L3
            movl    $LC0, 4(%esp)
            leal    -1032(%ebp), %eax
            movl    %eax, (%esp)
            call    _strcpy
            leal    -1032(%ebp), %eax
            movl    %eax, 4(%esp)
            movl    $LC1, (%esp)
            call    _printf
            leal    -12(%ebp), %eax
            incl    (%eax)
            jmp     L2
    L3:
            movl    $0, %eax
            leave
            ret
            .def    _printf;        .scl    3;      .type   32;     .endef
            .def    _strcpy;        .scl    3;      .type   32;     .endef
    Compiled the .c file with the -S switch on MinGW, and the assembly file is what was provided. All local variables have been allocated at the beginning of the function. Therefore, I would say you're not getting a real performance increase or decrease by allocating the buffer anywhere. At this point, you'd dealing with good C coding practice for readability, maintainability, etc. etc..

    In case there is any doubt, I compiled it with the buffer declared before i, and the assembly output was almost identical.

    I'm not really sure what you think you're gaining by using the first method anyway.
    Last edited by MacGyver; 06-03-2007 at 06:13 PM.

  4. #4
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591
    Thanks for that, its good to know the compiler does the optimization. What I was thinking for the first method was that if space was allocated for buf inside of the loop (L2) than precisely right after the jmp call to L2 and before the PC goes back to L2, the space allocated for buf will be removed off the stack and you will have saved sizeof(buf) more space in memory. Of course the time between the jmpl and when the PC is actually moved back to L2 is probably insignificantly short, and probably only another process running as a seperate thread could actually make use of the memory saved.
    Other than that, I prefer the first method mostly for readability, as it is more clear as to when buf is actually being used. Out of curiousity what do you (all) use in this situation?

  5. #5
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    I really don't think you're saving much space by doing it that way, especially since you're talking about the stack. The overhead just seems to be too much of a waste to try to save 512 bytes, or even 8192 bytes, or whatever BUFSIZ is on your system in this manner.

    I prefer to declare all my local variables at the beginning of the function, although just in recent days, I've been making an exception for programs that need long switch statements where certain local variables need only to be used in perhaps one case. Eventually, I think I moved most or all them to the top of the function anyway, so, I guess that exception doesn't count.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Assuming there's no performance hit, I would prefer the first form because the variable scope doesn't extend past where it's actually needed.

  7. #7
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    The first method can save you from the occasional error:
    buffer is declared before loop, initialized inside the loop and accessed after the loop (that should not be here - for example misspelled name).
    If loop is never executed - you access (by mistake) not initialized variable...

    If yo umove declaration of the buffer inside the loop - compiler will warn you about access to the not declared variable... And you can fix the access to the right variable immediately...

    So I always prefer to declare the variables in the minimum scope possible. (Sometimes even bringing additional scopes with
    Code:
    {}
    without if or loop)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The question of efficiency is pointless -- it costs nothing to create an auto variable because the compiler computes the total necessary size of the stack frame at compilation time. The variable "just exists" once you enter the function where it is declared.

    The fact that it is inside nested braces has nothing to do with anything. That just limits the scope of the variable, not the mechanism of its creation.

  9. #9
    Registered Abuser
    Join Date
    Jun 2006
    Location
    Toronto
    Posts
    591
    So your saying all variables in a program, regardless of their scope, are reserved space on the stack at run-time? Even across different modules?
    This seems to contradict what I recall (a very informed) someone warning that, in C99 mode, declaring variables anywhere other than the top of the stack could potentially generate problems if not enough memory could be allocated for that variable in mid-execution? According to the above, this would never be a problem, since all variables are allocated at run-time, right?

  10. #10
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    brewbuck is saying that variables local to functions are reserved when the function starts, not at program start.

    I would kind of hope that a compiler would not allow mid-declaration statements to actually allocate memory more than once from the stack. I can't see a real reason why you would want to do that.
    Last edited by MacGyver; 06-04-2007 at 04:47 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Please Help Me With This Code Of Implementing Stacks
    By raghu_equinox in forum C Programming
    Replies: 3
    Last Post: 10-19-2006, 07:22 AM
  2. ...multiplication using stacks
    By iiwhitexb0iii in forum C Programming
    Replies: 1
    Last Post: 10-09-2006, 01:28 AM
  3. Avioding Stacks
    By LoafOfBread34 in forum C++ Programming
    Replies: 8
    Last Post: 12-08-2004, 06:20 AM
  4. Looping questions
    By Peyote in forum C++ Programming
    Replies: 3
    Last Post: 09-15-2003, 11:01 PM
  5. Stacks stacks stacks
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 06-06-2002, 02:01 AM