7

If a function is declared as

static char *function(...) { ... }

Does it mean that this is a nonstatic function that returns a static char *, or a static function that returns a nonstatic char *?

Compare the following two functions. Which one is the correct use?

static char *fn1(void)
{
  static char s[] = "hello";
  return s;
}


static char *fn2(void)
{
  char *s = malloc(6);
  strcpy(s, "world");
  return s;
}
6
  • static char * isn't a type Commented Jan 30, 2015 at 19:48
  • Actually, the void is redundant and makes some compilers break. Commented Jan 30, 2015 at 19:48
  • @Prof.Falken, I think fn1(void), in C89 at least, means that I am declaring a function that takes no parameter, while fn1() means that the parameters are unspecified (that is, in old times when the idea of prototype has not been invented). Am I wrong? Commented Jan 30, 2015 at 19:56
  • @TavianBarnes. Thank you for the concise response! Commented Jan 30, 2015 at 19:58
  • I am not sure, but I recognize the practice of using void fn1(void) from olden days. Whether it is C89 or just malpractice, I don't know. But I have seen recent some compiler barf on it, maybe Visual Studio. Commented Jan 30, 2015 at 20:12

4 Answers 4

8

static applies to the function, not its return type. Both of these functions are correct—the difference is that s will be initialised once on the first call to fn1, and all calls to fn1 will share s; whereas in fn2, a new s will be allocated on every call. And since both fn1 and fn2 have static linkage, they will be private to the translation unit (source file, approximately) where they are defined.

Sign up to request clarification or add additional context in comments.

Comments

3

static before the function applies to the function, not its type (or even part of it, like the return-type):
It means the function has static linkage, aka is translation-unit/file local (and thus very likely to be inlined).

Both functions are correct, though they have different semantics:

  • The first returns a pointer to a static array, whose contents may be modified. Beware of concurrency and re-entrancy issues if you do that though.
  • The second allocates some heap-memory, initializes it with a string, and returns that. Remember to free it.

Comments

3

Both your function definitions are correct.

Point to note, static here is used to limit the function to file scope, not to specify the return type, i.e., this function can be used [called] by the other functions present in the same file, but not by the functions which are present in some other files, though they might have been compiled and linked together to form the binary.

Comments

1

The static keyword when used with a function definition says that the function has file level scope. This means the function name is only visible within the file itself. The static keyword used in a function definition modifies the function name visibility and does not modify the function return type.

So a function declared static can return any kind of a type.

The use of static on a variable defined in a function body is used to indicate that the variable is to be created at the point when the application is loaded and started. So if you use the static modifier on a variable within a function, that variable is not created on the stack when the function is called. It exists independently of when the function is called. However the variable's visibility is only within the function.

In your example you have a function that is returning the address of a static variable. You can do this however you must understand that this use is not thread safe. In other words all threads calling the function will get the same variable at the same memory location and not their own version of the variable.

You must also understand that if you return the address of a static variable you can also cause problems with reentrancy and recursiveness. The reason is that variables on the stack provide for reentrancy and recursiveness since each time the function is called, a new frame is added to the stack so each function call has its own stack frame hence its own set of variables.

This is a known issue with the old strtok() function in the Standard C library which used a variable within the strtok() function to maintain a state between calls using NULL as the string address of where the last call to strtok() left off when parsing a string. I have seen an issue where a function called strtok() to begin parsing a string and then called another function which in turn called strtok() to begin parsing a different string. The result was some really strange errors and behavior until the cause was figured out.

Using the static modifier on a global variable within a file will create a global variable that can be shared by multiple functions within the file. However like using the static modifier on a function name, a static variable will only have file scope visibility.

// .. top of a file of C source code

static int aStaticInt = 0;  // a static int that can be shared by all functions in the file but is visible only in the file
int aNonStaticInt = 0;  // a non static int that is visible outside of the file

static int myStaticFunc (void)
{
    // a function that is visible only within the file
}

int myNonStaticFunc (void)
{
    // a function that is visible outside the file as well as inside the file
}

1 Comment

Thank you sir for the thorough explanation!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.