2

Is the following code "correct"? Or would it be undefined behavior?

// myfile.c
static char x[10][10];

char* my_function() {
    return x[0];
}

my_function is being used in a shared library, so I would think it's not safe to access its return value outside the file/compilation-unit (due to the static keyword).

J B
  • 311
  • 4
  • 12
  • 4
    Perfectly legitimate. The array can only be accessed by name from within the file; it can be accessed by pointer if some function in the file such as `my_function()` makes the pointer available. That's a deliberate design feature in C. (You can even make pointers to static functions available by returning a pointer to the function.) – Jonathan Leffler Aug 17 '18 at 16:20

3 Answers3

5

The variable x is not visible by that name outside of myfile.c, however because it resides at file scope, i.e. it has static storage duration, its lifetime is still the lifetime of the whole program.

So it is valid to return a pointer to static data between source files.

dbush
  • 205,898
  • 23
  • 218
  • 273
4

This code would not be undefined behavior, in the sense that the pointer to storage of x returned by your function would remain valid even after your function exits. In other words, this does not create the problem that you get when you return a pointer to locally-allocated automatic storage.

A problem you may get by returning this pointer directly is that the callers may not respect the boundaries of x's storage, and access memory past my_function()+sizeof(x). This could be fixed by providing functions to read and write x without returning a pointer to it.

Note: Using static makes the name of the variable x inaccessible, not its storage. The idea is to let other modules define their own variables x without creating a name collision.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

There's two different things that 'static' variables do. If you declare a variable as static within a function, then the memory allocated to it within the function remains accessible even after the function returns, example:

#include <stdio.h>

char *func1()
{
    static char hello[] = {"Hello, world!\0"};
    return hello;
}

char *func2()
{
    char goodbye[] = {"Goodbye!\0"};
    return goodbye;
}

int main( int charc, char *argv[] )
{
    printf( "%s\n", func1() );
    printf( "%s\n", func2() );
}

The call to func1() is valid, as the variable "hello" declared inside the function was set as static, so it remains accessible even after the function returns.

The call to func2() is undefined behavior as once the function returns the memory allocated to "goodbye" is returned to the operating system. Generally, you will get a segmentation fault and the program will crash.

The other thing 'static' will do is when a variable (or function) is declared as static at the file level, that variable (or function) will only be accessible within that file. This is for data encapsulation.

So if I have file1.c with the following code:

static *char hello()
{
    static char hi[] = {"Hi!\0"};
    return hi;
}

And then in file2.c I have:

#include <stdio.h>

extern char *hello(); //This lets the compiler know that I'm accessing a function hello() in another file

int main( int charc, char *argv[] )
{
    printf( "%s", hello() );
    return 0;
}

If I compile it with gcc file1.c file2.c -o test

The compiler will complain that it can't find hello().

Will
  • 33
  • 1
  • 8