Initialize static structure - c

I have the following structure:
typedef struct
{
uint8* buffer;
uint32 bufferLength;
} SRequest;
and a function:
void somefunction(const SRequest* request)
{
//The following initialization of the pointer to static structure is not working
static SRequest* request_ptr = {.buffer = request->buffer,
.bufferLength = 0};
.
.
}
Is there another way I can initialize the request_ptr?

You are trying to initialize a pointer with a value that is not a pointer but rather a struct. That cannot possibly work.
Moreover, initializers for objects with static storage duration must be compile-time constants. This constraint makes sense when you recognize that initialization of such objects happens (logically) before program execution starts. All file-scope variables have static duration, as do local variables declared static, such as your request_ptr. You are trying to initialize your static pointer with a value that is not a compile-time constant.
It is unclear what you are really after, here, but if you are trying to create, on each call, an SRequest that points to the same buffer that the argument does, then that could be this:
void somefunction(const SRequest* request)
{
SRequest local_request = {.buffer = request->buffer,
.bufferLength = 0};
.
.
.
}
Note there that I make local_request an automatic variable rather than a static one, so that its initializer is applied on every call, and that I make it a struct, not a pointer to one.
On the other hand, if your objective is to have an SRequest that is initialized on the first call to the function with values derived from the argument to that call, and thereafter persists across function calls, then you want something like this:
void somefunction(const SRequest* request)
{
static int initialized = 0;
static SRequest local_request;
if (!initialized) {
local_request.buffer = request->buffer;
local_request.buffer_length = 0;
initialized = 1;
}
.
.
.
}
You might be able to do without the initialized variable if a member of local_request would be suitable in its stead. For instance, perhaps it would work for your purposes to instead test weather local_request.buffer is NULL.
In any event, it's unclear to me why you would want the local variable to designate a pointer instead of a structure. There are potential reasons why you might indeed want that, but it's not evident that any of those apply.

As the title of the question seems more explicit than the cited one by terence hill, it might be interesting to have the answer here.
You have to use "compound literal", which is defined in the C99 standard:
void somefunction(const SRequest* request)
{
//The following initialization of the pointer to static structure is not working
static SRequest* request_ptr = &(SRequest){
.buffer = request->buffer,
.bufferLength = 0};
}

Related

Let static function variable take value of parameter in C

I am writing a data mashing function where I'm modifying audio data over time for a sort of dynamic bit-crusher audio filter. It is convenient for me to use static variables because their values carry over between function calls and this helps me achieve some interesting time-based effects by incrementing and so forth across rendering callbacks.
For example, one effect uses a sin function to modulate some sound effect over time. Like so:
void mangle(float * data, int n) {
static bool direction = false;
static float bottom = 0;
static float top = n;
static float theta = 0;
theta += 5;
// data = sin(theta) etc..
So I wish theta to be initialized once and than modified over time. Likewise, top wants to be static variable because I modify it later in the function also. In addition, top should take on the value of parameter n because n changes based on program state. But when I go to assign n to top, I get the compiler error
Initializer element is not a compile-time constsant.
Is there a way to assign a parameter to a static variable? Is there another way to accomplish what I want without static variables? I am aware I could use instance variables but I find that to be too much.
static variables are initialized before the program execution begins, so you cannot use a variable value to initialize a static variable. You'll need a compile-time constant value to initialize the static variable.
Quoting C11 standard, chapter §6.2.4, Storage durations of objects (emphasis mine)
[..] or with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.
However, you can always assign a new value to the static variable.
That said, coming to the initialization part, as per chapter §6.7.9,
If an object that has static or thread storage duration is not initialized
explicitly, then
- ...
- if it has arithmetic type, it is initialized to (positive or unsigned) zero
- ...
so, you need not initialize the static floats explicitly to 0. You can assign any value, whatsoever later in the code.
In your case, top is a local static variable.
It is like global static variable and global variable that they all have static storage duration and they have value before the code startup.
The reason you have error similar to this case:
int a;
int b = a; \\initializer is not a constant
int main() {
...
}
With your purpose, use top as a global variable is a right way to go.
What you should do is create a struct that holds the data that is needed across calls and pass a pointer to the struct to the function. If you wnat to get fancy, you can create functions that allocate, initialize and free such a struct (and the user of the functions never needs to know what the contents of the struct are.
Something like:
struct mangle_t {
bool direction;
float bottom;
float top;
float theta;
};
struct mangle_t* mangle_open(void)
{
struct mangle_t* m = malloc(sizeof *m);
if (m) {
memset(m, 0, sizeof *m);
}
return m;
}
void mangle_close(struct mangle_t* m)
{
free(m);
}
void mangle(struct mangle_t* m, float * data, int n) {
m->top = n;
m->theta += 5;
}
As far as assigning a parameter to a static variable, you can just perofrm the assignment like any other variable (however, not as an initialization in the variable's declaration - that only happens once).
I'm not sure if you want to initialize top once and then keep it, but if so, this is what I would do:
void mangle(float *data, int n) {
static float top = -1; // Assuming that n will never be -1
if (top == -1)
top = n;
// .....
}
If you don't need to keep the value of top over function calls, there is no need to declare it static.

incorrect pointer value passed to a C function

I have a bug in which an incorrect value gets passed as an argument to a function in a C program. The way it works is, I declare a static pointer to a typedef-ed data structure as a global variable. There is an initialization function where this variable is initialized. This function allocates memory, initializes data fields and returns the pointer. Something like this:
static my_type *my_ptr;
...
void init(void){
my_ptr = init_my_type();
}
The function init_my_type is pretty straight forward:
void *init_my_type(void){
my_type *x = malloc(sizeof(my_type);
x->arg1 = 0;
... // more field initializations
return x;
}
Later on I use my_ptr as an argument to another function:
void do_stuff(void){
func(my_ptr);
}
The problem I have is that I seg fault in the guts of func when some of the data in the data structure that my_ptr points to is accessed.
When I run the debugger I get a nice looking hex value when I break on the init_my_type:
(gdb) finish
Value returned is $26 (void *) 0x79b6c0
Later, inside the do_stuff function, my_ptr has the same hex value:
(gdb) print my_ptr
$26 = (my_type *) 0x79b6c0
but, when I break on func the argument it gets has a totally different value.
Breakpoint 2, func(arg=0x1388)
I am type-punning pointers all over the place, but I don't see that that should change the address in memory that they point to, right? Also, the function func is declared inline but why should that affect this? This all seems correct to me -- it is entirely possible that I'm doing something stupid that I don't see.
Here is a complete program of the simplified code. In reality, all these functions don't get called by main, but by dynamically loaded helper functions. Still, I don't see how the address pointed to by my_ptr should change when passed to func.
#include "stdlib.h"
#include "stdio.h"
typedef struct _type{
int *i1;
float *f1;
}my_type;
static my_type *my_ptr;
void *init_my_type(void){
my_type *x = malloc(sizeof(my_type));
x->f1 = malloc(sizeof(float));
x->i1 = malloc(sizeof(int));
x->f1[0] = 123.456;
x->i1[0] = 789;
return x;
}
void init(void){
my_ptr = init_my_type();
}
inline void func(void *arg){
my_type *x = (my_type *)arg;
printf("%d %f\n", *x->i1, *x->f1);
}
void do_stuff(void){
func(my_ptr);
}
int main(void){
init();
do_stuff();
}
The following is not the cause of the issue (and can't, since static globals are initialised to zero by default). Though the basic idea is still relevant: whether the passed pointer is really the same that got initialised.
A wild guess:
static my_type *my_ptr;
Could it be that this line is part of some header file? Because then you have a global my_ptr in every source file that includes this header.
Since you wrote that this is a very large project, I assume that you separated the code and put it into multiple source files. Assuming the init function is in a different source file than the using function, then this would mean they're accessing different pointers. While the one init deals with gets initialised, the one func is using is uninitialised.
To check this you should print the address of the global pointer variable (&my_ptr) in both functions.

initializing a function externally

I would like to return a function with a variable inside it that I can initialize inside the function that returns it. Possible, or no?
int get_char (char *c)
{
static circular_queue *cir; // this needs to be initialized in the function below
if (circular_queue_empty(cir))
return 0;
else
*c = circular_queue_pop(cir);
return 1;
}
int (*generate_get_char(circular_queue *cir)) (char *c)
{
// do something to set cir
return &get_char;
}
I am passing the pointer to getchar into an API that I do not control so I cannot change the format of get_char; that being said, is there a better way of doing this as I am pretty sure the above is not possible. (I would rather not use a static global, but thats all I can think of doing).
TY
Variables which have static storage allocation are default initialized to zero. Therefore, the following statements are effectively equivalent.
static circular_queue *cir;
// equivalent to
static circular_queue *cir = 0;
// equivalent to
static circular_queue *cir = NULL;
The variable cir has function scope, i.e., it can be accessed only in the function get_char. Therefore, the answer to your question
I would like to return a function with a variable inside it that I can
initialize inside the function that returns it. Possible, or no?
is no. You need a global variable which is visible to both the functions get_char and generate_get_char. Also, note that a function name implicitly converts to a pointer. Therefore, the following are equivalent -
return &get_char;
// equivalent to
return get_char;
This is not possible - cir is accessible only from get_char and there is no way to access it from outside. You need a static global visible by both functions.

When do programmers use 'static' and 'const' keywords?

I am doing research on static and const keywords.
Static: Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.
const: You use the const keyword to declare a constant field or a constant local. This keyword specifies that the value of the field or the local variable is constant, which means that it can't be modified.
I would like to know about example when programmers would use static and const keywords.
const variables, or constant, would be used to declare a value that won't change or you want to prevent from being changed. For example, Pi could be declared as a constant in C++.
const double kPi = 3.14159265359;
static variables are a bit different. There is only one instance of the static variable that persists across classes\functions.
For example:
void foo()
{
static int bar = 0;
printf("%d\n", bar);
++bar;
}
int main()
{
int i;
for(i = 0; i < 5; ++i)
{
foo();
}
}
Would print:
0
1
2
3
4
Even though bar goes out of scope, its value is still in memory, so its only initialized once. Each time the foo() is called, that value gets incremented.
Edit:
To clarify, the compiler will actually reserve memory for the static variable within the assembly code that it produces. Additionally, the static keyword also tells the compiler to initialize the variable exactly once. The scope of the variable is the same (inside the foo function), but it is only initialized once in the above case. Automatic variables (such as int i) are pushed onto the call stack when the function is called.
(All of this is for Langage C++)
Hi, you can use const and static keywords in few cases, for exemple :
Const
First, used to say that the variable cannot be modified.
int main()
{
const int toto[4] = {0, 1, 2, 3};
return (0);
}
// We cannot modify toto after it declaration, why is it usefull? It keeps the state of your program design
Second, used to say that a method do not modify the object state.
class toto
{
int i;
public:
int geti() const;
}
// All getter in CPP use it. Why is it usefull? Developper who use the class know that he do not modify the object state
Third, used to say that the parameter pass to a function isn't modify by the function.
int function(const std::string &str)
{
// function cannot modify the object string pass in parameter
}
Static
First, used to say that a implemented function is know only inner a single file.
static int fct()
{
return (0);
}
// You can ony call function fct() if you are inner the file who it is implemented
Second, used to say that a argument or method is common to all object of the same class.
class toto
{
public :
static int getLol();
};
// Every object totoObj1, totoObj2 ... will call same function
Third and the last one, used to say that a variable do not change state between multiple call of the same function where it is declared
void fct()
{
static i = 0;
std::cout << ++i << std::endl;
}
// This function are going to print 1 then 2 then 3 ...
If you have any questions, you are welcome :)
If you want to have any variable/method to be available irrespective of an object you go for a static member but if you want the same to be unmodifiable as well then const is the solution. Following example can help you understand this.
In below example
PI is defined as a constant and can not/should not be changed
ONLINE holds number of users online, it can change but should be available irrespective of objects
public class Example
{
//PI should not be changed, with reasons known that it is a constant
public const double PI = 3.14;
//Users currently using the application
public static int ONLINE = 0;
public Example(){ ONLINE++; }
public void dispose(){ ONLINE--; }
public static int loggedInUsers(){ return ONLINE; }
public void GetArea(int radius){return PI*radius*radius; }
}

Store pointer to array in file scope from array paramter in a function

I am rebuilding an application to comply with MISRA-rules and using QA-C to analyze my code.
One of those annoying rules involve pointers and arrays.
You can't say:
char foo[10];
char * bar = &(foo[0]);
bar[5] = 'a';
Nor can you then do:
*bar = 'a';
bar++;
My problem involves two functions and a file-scope variable.
Originally this code did the following (bit-pseudocode-like):
static char * bufferPtr;
static void foo_a(char * buffer /* other params */)
{
bufferPtr = buffer;
/* some logic goes here */
switch()
{
case 'b':
foo_b(/* some param */);
}
static void foo_b(/* parameters */)
{
if (/*something*/)
{
/* some logic */
foo_c(/* data-param */);
/* some logic */
}
else
{
/* some logic */
foo_c(/* data-param */);
/* some logic */
}
}
static void foo_c(char data)
{
*buffer++ = data;
}
I've tried to rewrite it to the following:
static char (*bufferPtr)[];
static char bufferIndex;
static void foo_a(char buffer[] /* other params */)
{
bufferPtr = &buffer;
bufferIndex = 0;
/* same */
}
static void foo_b(/* parameters */)
{
/* same */
}
static void foo_c(char data)
{
(*bufferPtr)[bufferIndex] = data;
bufferIndex++;
}
But then both misra and my compiler (softune, by Fujitsu) complain.
Compiler says:
assignment incompatible pointer types from CHAR **' toCHAR (*)[]': operator `='
Misra says:
[C] Right operand of assignment is not of compatible pointer type.
Address of automatic object exported to a pointer with linkage or wider scope.
However I do need to be able to index an array in the foo_c function. Or are there other ways to and follow misra and make my code work.
If I do the following in the same file:
static CHAR foo[10];
static CHAR (*bar)[];
static void f(void)
{
bar = &foo;
}
Then nor Misra nor my compiler complain about anything.
This doesn't make sense to me:
static char (*bufferPtr)[];
static char bufferIndex;
I'd make it like that:
static char *bufferPtr_new;
static int bufferIndex_new;
And replace every *bufferPtr with bufferPtr_new[bufferIndex_new]
But perhaps explain to us what's wrong with current code, according to MISRA.
Not sure if you're going to like this:
static char *(bufferPtr[10]); /* must have a size */
static char bufferIndex;
static void foo_a(char buffer[])
{
*bufferPtr = buffer;
bufferIndex = 0;
/* etc */
}
Hope it helps.
static void foo_a(char * buffer /* other params */)
The argument buffer is a pointer, not an array, so trying to treat it as an array elsewhere is going to fail.
The sensible thing would be to have foo_a accept a pointer to an array (char (*buffer)[N] for some N) or a pointer to a struct containing an appropriate sized array. You can then assign to a file static char (*bufferPtr)[N] or (better) pass the array pointer through your call chain.
One of those annoying rules involve pointers and arrays. You can't say: ....
char foo[10];
Perfectly fine, except for the char type which isn't allowed.
char * bar = &(foo[0]);
Fine if foo is declared with array syntax. If foo was declared using pointer syntax it violates rule 17.4. See the fix for rule 17.4 further below.
Also, the parenthesis doesn't make any sense whatsoever, neither for MISRA nor for other reasons.
bar[5] = 'a';
Perfectly fine.
*bar = 'a';
Perfectly fine.
bar++;
This isn't allowed by rule 17.4, which is stating that array indexing is the only allowed form of pointer arithmetic. It is indeed a very dumb rule and I believe it will be removed in the next version of MISRA. I actually once addressed this rule with the committee and they couldn't give any rationale for the rule other than cosmetics.
The solution is to create a deviation from MISRA-C for this rule, that's what most MISRA-implementations seem to do. Don't just blindly follow MISRA. 90% of the rules are good, but there are some odd ones lacking a rationale.
I've changed the flow of this code to just pass the buffer parameter to each subsequent version.
It is ugly, but it works and is somewhat safe. 'according to misra'

Resources