Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Violating static function in C

Tags:

c

static

In one interview I was asked, if in one file A, some static function is defined and in file B you want to use this static function -- how you will use it?

My answers were:

  1. declaring in .h file But if we declare that in a header file, other files which will include this also have access to this static function.
  2. wrapper concept: Declaring a new function newfun in file A, which will call static function and calling this newfun in file B.

But he was not satisfied with these answers.

Can you please provide me some better solution to violate static.

like image 652
rose Avatar asked Oct 07 '15 12:10

rose


People also ask

What is the static function in C?

Static functions in C are functions that are restricted to the same file in which they are defined. The functions in C are by default global. If we want to limit the scope of the function, we use the keyword static before the function.

What happens when a function is static?

A static function in C is a function that has a scope that is limited to its object file. This means that the static function is only visible in its object file. A function can be declared as static function by placing the static keyword before the function name.

What is the effect of removing static keyword?

If your code compiles after removing the static keyword, then you do not have two functions with the same name and it will work just like any normal function. It will have no run time penalty.

Are C functions static by default?

In C, functions are global by default. The “static” keyword before a function name makes it static. For example, below function fun() is static.


3 Answers

Perhaps they wanted to hear about function pointers?

You can create a pointer to the function, and call it using that pointer.

One possible scenario where this is reasonable is if you have a callback function that you don't want to be callable by everyone, and you give the pointer as an argument to some register_callback function.

Callback functions were used extensively, for example to let the user of a GUI API provide code for what should happen when a button is pressed. Nowadays, with object-oriented languages, it is more common to subclass a class and define or override methods, such as the Android View class and the method OnClickListener, but C# delegates are very similar to C function pointers.

To illustrate the principle, here is the source code (the file "B" in the original question) for some sort of library, where the main component is the do_stuff function:

#include <stdio.h>
#include "some_library.h"

void (*stored_callback)(void) = NULL;

void register_callback(void (*callback)(void)) {
    stored_callback = callback;
}

void do_stuff(void) {
    printf("Doing stuff...\n");
    printf("Calling callback...\n");
    if (stored_callback != NULL)
        stored_callback();
}

This header, some_library.h, file shows the API of that library:

extern void register_callback(void (*callback)(void));
extern void do_stuff(void);

And here is how the library is used (the file "A" in the question):

#include <stdio.h>
#include "some_library.h"

static void my_callback(void) {
    printf("Inside the callback!\n");
}

int main(void) {
    register_callback(my_callback);
    do_stuff();
    return 0;
}
like image 166
Thomas Padron-McCarthy Avatar answered Sep 21 '22 19:09

Thomas Padron-McCarthy


My interview answer would be "You can't."

(Because the question says "in file B you want to use this static function" and it didn't say you are allowed to modify file A.)

like image 31
Paul Ogilvie Avatar answered Sep 24 '22 19:09

Paul Ogilvie


I'm assuming you don't have access to the source of the static function or else you could just remove the static keyword or expose the function via an exported wrapper or global function pointer.

You can still use the static function if you use objcopy to manually change the visibility on the symbol in the object file / library.

Suppose this is the (unaccessible) static function:

//static.c
#include <stdio.h>
static void fun(){
  puts("Hello world");
}

Suppose you only have static.o, obtainable with gcc -c static.c.

Now, let's assume you want to link static.o with main.o made from

//main.c
void fun();

void main(){
  fun();
};

To be able to link it, you need to turn

$ nm static.o
0000000000000000 t fun
                 U puts

into

0000000000000000 T fun
                U puts

You can do that with:

objcopy --globalize-symbol=fun static.o global.o 

Now you can link with global.o instead of static.o.

$ gcc main.o global.o && ./a.out
  Hello world
like image 41
PSkocik Avatar answered Sep 21 '22 19:09

PSkocik