In C on a small embedded system, is there any reason not to do this:
const char * filter_something(const char * original, const int max_length)
{
static char buffer[BUFFER_SIZE];
// checking inputs for safety omitted
// copy input to buffer here with appropriate filtering etc
return buffer;
}
this is essentially a utility function the source is FLASH memory which may be corrupted, we do a kind of "safe copy" to make sure we have a null terminated string. I chose to use a static buffer and make it available read only to the caller.
A colleague is telling me that I am somehow not respecting the scope of the buffer by doing this, to me it makes perfect sense for the use case we have.
I really do not see any reason not to do this. Can anyone give me one?
CodePudding user response:
It really depends on how filter_something is used. Take the following as an example
#include <stdio.h>
#include <string.h>
const char* filter(const char* original, const int max_length)
{
static char buffer[1024];
memset(buffer, 0, sizeof(buffer));
memcpy(buffer, original, max_length);
return buffer;
}
int main()
{
printf("%s\n", filter("everybody", 10));
printf("%s %s %s\n", filter("nobody", 7), filter("somebody", 9), filter("anybody", 8));
if (strcmp(filter("same",5), filter("different", 10)) == 0)
printf("Strings same\n");
else
printf("Strings different\n");
}
The output when gcc is used is
everybody
nobody nobody nobody
Strings same
When filter is used by itself, it behaves quite well. When it is used multiple times in an expression, the behaviour is undefined.
In C , this technique is often used when returning objects with the same consequences.
CodePudding user response:
Pro
- The behavior is well defined; the static
buffer
exists for the duration of the program and may be used by the program afterfilter_something
returns.
Cons
Returning a static buffer is prone to error because people writing calls to the routines may neglect or be unaware that a static buffer is returned. This can lead to attempts to use multiple instances of the buffer from multiple calls to the function (in the same thread or different threads). Clear documentation is essential.
The static
buffer
exists for the duration of the program, so it occupies space at times when it may not be needed.
CodePudding user response:
It is true that the identifier buffer
only has scope local to the block in which it is declared. However, because it is declared static
, its lifetime is that of the full program.
So returning a pointer to a static
variable is valid. In fact, many standard functions do this such as strtok
and ctime
.
The one thing you need to watch for is that such a function is not reentrant. For example, if you do something like this:
printf("filter 1: %s, filter 2: %s\n",
filter_something("abc", 3), filter_something("xyz", 3));
The two function calls can occur in any order, and both return the same pointer, so you'll get the same result printed twice (i.e. the result of whatever call happens to occur last) instead of two different results.
Also, if such a function is called from two different threads, you end up with a race condition with the threads reading/writing the same place.