Possible to initialize static variable by calling function - c

Is this possible?
static bool initialize()
{
TRC_SCOPE_INIT(...);
...
}
static bool initialized = initialize();
To make a very long story short, I need to call a series of macros (to initialize debugging messages) as early as possible (before thread X is started, and I don't have the ability to know when thread X is started).

If you're using GCC (or clang), you can use __attribute__((constructor)):
static bool initialized = false;
__attribute__((constructor))
static void initialize(void) {
initialized = true;
// do some other initialization
}
int main(int argc, char **argv) {
// initialize will have been run before main started
return 0;
}

When I originally looked at the question, it was tagged both C and C++. The code could be C or C++ because bool is a type in C99 and C11, just as it is in C++ (almost; in C, you need the <stdbool.h> header to get the name bool).
The answers for the two tags are:
In C++, yes.
In C, no.
They are not the same language. If you need a demonstration, this is as good an example as any.

This should be alright provided the "stuff" you are initializing is defined in the same translation unit as the call to the function that initializes it. In addition, it must be defined above the call site. Otherwise you risk undefined behavior due to use of uninitialized values.
One way to get around this is to use a pointer instead. A statically initialized pointer is compiled into the executable image, so there's no risk of undefined behavior if it's used by statics defined in other translation units. In your static initialization function you dynamically allocate the "stuff" and set the pointer to point to it so you can access it later.

(Since you mentioned threads, I'm going to assume you have POSIX thread functions at your disposal.)
The pthread_once function exists for this exact purpose. Anywhere you need to be sure initialize has already been called, write:
pthread_once(&init_once, initialize);
where init_once is defined with static storage duration, and possibly with external linkage if needed, as pthread_once_t init_once.

Related

Class approximation in C - Is this witchcraft or technically acceptable?

I need to do a large Project in C and C only, without external librairies (except for SDL).
I started looking for ways to do some kind of class in C, what led me to that :
typedef void (*voidFunction)(void);
typedef struct{
int id;
voidFunction printId;
} Object;
Object *new_Object(int id){
Object *newObject = malloc(sizeof(Object));
newObject->id = id;
void printId(){
static Object *this = NULL;
if(!this) this = newObject;
printf("%d\n", this->id);
};
newObject->printId = printId;
return newObject;
}
int main(){
Object *object = new_Object(5);
object->printId();
object->id++;
object->printId();
return 0;
}
Output of main :
5
6
So this works, but does it seems reasonable ?
Should I expect a backlash if I use this kind of architecture for a big project? Maybe I'm typing out of my allocated memory without realizing it?
Techniques for implementing polymorphism in C are long established, check this answer for instance https://stackoverflow.com/a/351745/4433969
Your implementation seems to be broken. Nested functions are non-standard extension. I also have doubts about static this variable.
The non-standard nested function printId is used incorrectly. In GCC documentation Nested functions one can read:
If you try to call the nested function through its address after the containing function exits, all hell breaks loose.
The nested functions are called via trampolines, the small pieces of executable code located on stack. This code is invalidated when the parent function exits.
Though as the functions does not refer to any local variables the code will likely work. The compiler will likely avoid trampolines but rather create a kind-of "anonymous" static function.
The idiomatic solution should take a pointer to "Object" as an argument rather than use a static variable.
typedef struct Object {
int id;
void (*printId)(struct Object*);
} Object;
void printId(Object *this){
printf("%d\n", this->id);
};
...
object->printId(object);
There are advantages for using a struct to organize data for bulk processing. However, the only advantage of using the function pointer rather than calling the function directly would be:
To allow the function pointer to point to different functions having the same type for different instances of the object.
To hide the "member" function definition from the linker. For example, the function printId could be declared as static within the module containing the definition for "constructor" new_Object.

Why is the address of a nested function (GNU extension) in GCC considered "not constant" by the compiler?

The GNU C compiler contains a nice extension to the C language, called Nested Functions.
However, the documentation is unclear in some points. For example, it says that
It is possible to call the nested function from outside the scope of its name by storing its address or passing the address to another function [...]
If you try to call the nested function through its address after the containing function exits, all hell breaks loose.
If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it’s not wise to take the risk.
If, however, the nested function does not refer to anything that has gone out of scope, you should be safe.
So on one hand, it says that if you call a nested function after the containing function exits, "all hell breaks loose", but a few sentences ahead it says that there are circumstances in which it is fine to do so.
I imagine that by "things going out of scope" they mean automatic variables, so in particular it should be safe to refactor
static int f() { ... }
int outer() {
... // some use of f
}
into
int outer() {
int f() { ... } // f does not refer to outer's local variables
... // some use of f
}
if there are no other uses of f in the module than those in the outer function, even assuming that the outer function somehow leaks the address of f beyond its own scope.
However, I was surprised to find out that the following code doesn't compile
int main(void) {
void nested_function(void) {}
static const struct { void (*function_pointer)(void); } s = {
.function_pointer = nested_function
};
return 0;
}
with the complaint that initializer element is not constant (i.e. nested_function).
Is there any reason for this limitation? (I can't imagine the address of a function being non-constant, even if it is nested)
In the current GCC implementation, an unnecessary static chain pointer for nested functions is only omitted during optimization. It is not reflected in the type system (unlike a C++ lambda that does not bind anything). Without optimization, the compiler has to create a trampoline on the stack, so the function address is actually non-constant in that case.

static pointer, initialiser is not constant? [duplicate]

This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 6 years ago.
What I thought static pointer is like other static variables, ones initialised with an value it have same value till end, like that the same address will be held in the static pointer. But in this case the compiler is throwing error
//initialiser element is not constant static int *a = &b[0];
#include <stdio.h>
int main(void)
{
int b[2];
static int *a = &b[0]; // removing static the program works well.
printf("%u",a);
a = &b[1];
printf("%u",a);
return 0;
}
So what is the use of static pointer?
In C, your code doesn't make sense. b has automatic storage duration so conceptually will have a different address each time main is encountered. The static will be initialised only once, and on subsequent invocations of main it may well point to something invalid.
But, and this is the interesting bit, in C++ it ought to make sense since you are not allowed to call main yourself: the behaviour on your doing so is undefined. So the inference of this is that the compiler ought to know that the static is valid for the lifetime of main, and compile the code! Perhaps there is something in the C++ Standard that explicitly forbids this.
In C you are allowed to call main recursively (even implicitly recursively), so the compiler ought to emit an error.
You have two options. Add static to int b[2], or remove it from int *a.
The address of b isn't static. It's variable, because b is a variable with automatic storage.
There may be confusion about static vs const.
Const variables will keep the same value from the time they are initialized until they go out of scope, unless const_cast<> is used, though as #Bathsheba mentioned in comment, use of const_cast<> on a variable declared const is undefined.
Static means it will get initialized at the spot first reaches but then not go out of scope until the end of program execution.

C: how to declare a static function that returns a nonstatic string?

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;
}
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.
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.
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.
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
}

initializing static variable with a function call gives compilation error?

#include <stdio.h>
int foo(){
return 1;
}
int main(void) {
static int q = foo();
return 0;
}
Here is a link for the same. This is a C code and not C++. It compiles and run fine in C++ but not C.
This code was getting compilation error. Can someone please explain why is it getting error? Can static members only be initialized by constant values ? In C++ we need to DEFINE static members after declaring them , why is it not required in C ? I couldn't find any thread with similar query or a good answer.
Global and static variables can only be initialized with constant expressions known at compile time. Calling your foo() function does not constitute using a constant expression. Further, the order in which global and static variables are initialized is not specified. Generally, calling foo() would mean that there must be a certain order, because the function can reasonably expect some other variables to be already initialized.
IOW, in C, neither of your code is executed before main().
In C++ there are ways around it, but not in C.
All the static variables are compile time and the function is giving the output at run time so you are initializing a compile time variable with a run time variable which is not possible so it is giving error.
Another example may be as follows
int main()
{
int p=9;
static int x=p;
}
the above code is also gives you compile time error,The cause is same as above.
If you are doing this in C rather than C++ you can only assign static variables values that are available during compilation. So the use of foo() is not permitted due to its value not being determined until runtime.

Resources