Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this buffer defined inside of a loop?

Tags:

c

tcp

sockets

I've always been under the impression that I shouldn't define a variable inside of a loop because it's unnecessary or wasteful. This makes me wonder if the following recv() function needs a fresh buffer for each iteration of the loop:

while (totalBytesRecvd < echoStrLen)
{
    char buffer[BUFSIZE];
    numBytes = recv(sock, buffer, BUFSIZE - 1, 0);
    ...
    totalBytesRecvd += numBytes;
    buffer[numBytes] = '\0';
    fputs(buffer, stdout);
}

The documentation for recv() doesn't mention anything about how it uses the buffer pointer. For a better understanding, I tried defining the buffer just before the loop, and recv() appears to overwrite the buffer, instead of redefining it. Which makes sense since recv() is passed a pointer to the beginning of the buffer.

Is there a specific reason to define a buffer over and over again inside of a loop? Or is my basic understanding of this correct?

like image 859
Nocturno Avatar asked Sep 23 '12 00:09

Nocturno


3 Answers

recv, as read and other similar functions, doesn't care about the previous content of the buffer, it uses it just to write the result.

Not that it would make a difference anyway: since you are not initializing your buffer, its content will be "undefined" even if you declare the variable as local to the loop.

Also, on most C implementations:

  • not initializing that variable means that will take whatever happens to be on the stack at that location, which in turn means that it'll be taking the same location as it were at the previous iteration, effectively giving you the exact same result as having the variable outside the loop.
  • stack allocations are cheap - in general they just require to adjust a register;
  • actually, they are even cheaper: usually the register adjustment is done just at the beginning of the function, accounting for all the local variables; the scoping of a local variable becomes just a compile-time construct, since it's allocated when the function starts.

Obviously, instead, if you initialized your variable it would be different - the code to perform the initialization would have to run at each iteration; but, as said above, there's no need to initialize anything, recv just doesn't care about the current state of the buffer.

like image 55
Matteo Italia Avatar answered Nov 03 '22 02:11

Matteo Italia


It is not wasteful. It declares the scope of this variable. The compiler may reclaim the space on the stack for other purposes not allocating more from the stack out of this scope. It requires no extra expenses at run time - the compiler calculates the necessary stack space at compile time and adjusts the stack pointer only once in the beginning of the function.

like image 5
Serge Avatar answered Nov 03 '22 04:11

Serge


Declaring a variable inside a loop just reserves stack space for it; it will not clear the contents or otherwise touch the variable. Thus, this style of declaration is no more expensive than declaring it outside the loop.

like image 2
nneonneo Avatar answered Nov 03 '22 02:11

nneonneo