Why is this buffer defined inside the loop?

I always had the impression that I should not define a variable inside the loop because it is unnecessary or wasteful. This makes me wonder if the following recv () function needs every loop repeat for a new 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 () says nothing about how it uses a buffer pointer. For a better understanding, I tried to define a buffer just before the loop, and recv () seems to overwrite the buffer rather than override it. Which makes sense since recv () is passed a pointer to the beginning of the buffer.

Is there a specific reason for defining a buffer over and over inside a loop? Or is my basic understanding of this correct?

+6
source share
6 answers

recv , like read and other similar functions, do not care about the previous contents of the buffer, it uses it only to write the result.

Not that it would matter in any case: since you are not initializing your buffer, its contents will be "undefined" even if you declare the variable as local to the loop.

Also, on most C implementations:

  • not initializing this variable means that everything that happens on the stack in this place will happen, which, in turn, means that it will be in the same place as in the previous iteration, which gives you the exact result as having a variable outside the loop.
  • Stacking is cheap - in general, they just require a register setting;
  • in fact, they are even cheaper: usually register adjustment is performed only at the beginning of a function that takes into account all local variables; the scope of a local variable becomes just a compilation time construct, since it is allocated when the function starts.

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

+8
source

This is not wasteful. It declares the scope of this variable. The compiler can return space to the stack for other purposes, without allocating more from the stack from this area. It does not require additional costs at runtime - the compiler calculates the necessary stack space at compile time and adjusts the stack pointer only once at the beginning of the function.

+5
source

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

+2
source

Defining a variable in a loop is only bad if it is expensive to build, and this is rarely the case in C.

Even with the most basic optimizations, he is not even going to change the modification of the stack pointer at each iteration of the loop. Many compilers will initialize the array in debug mode to zero, but if this buffer is not huge, this is unlikely to be a big problem.

In C ++, you might think about not declaring a variable with an expensive constructor, if you can only leave by building it outside the loop, but that won't be a problem here.

+2
source

I always got the impression that I should not define a variable inside the loop because it is unnecessary or wasteful.

You were always under the wrong impression and not only unfounded, but also very bad practice - premature optimization - against very good, declaring the variables as close as possible to their use.

+1
source

I also thought that moving declarations from loops would lead to faster code, especially for large structures like arrays. I think this often happens with malloc'd (heap) data, because you can spend a lot on overhead by calling malloc and freely in a loop. For stack data (like yours) I don't think this is like a big problem.

However, I recently encountered the opposite situation when I moved an ad from an inner loop and actually ended up with a slower code. I came up with several possible explanations for this:

  • When the ad was moved to a wider scope, the compiler could not optimize the code so efficiently.
  • In memory between iterations of the loop, more data was stored, which led to inefficient use of the cache.

Anyway, I don't have a good reference for this, but moving the definitions to or from loops can make the code faster or slower depending on the situation. You should measure the performance before and after changing the code to see if there is a difference.

+1
source

Source: https://habr.com/ru/post/926025/


All Articles