Initialize a struct - c

I am trying to initialize a struct but getting the following error messages in C:
error: initializer element is not constant
error: (near initialization for 'resource01.resource.role')
For URL it works, it's just the role which is not working. First I had a pointer on role and I assigned the address of the variable. I removed the pointer because I don't need it and I can t assign just a value to the variable. What am I doing wrong?
static char const resource01Url[] = "/dummy";
static int const resource01Role = 2;
static struct RestResourceNode_S resource01 =
{
{
resource01Url,
resource01Role,
&DummyHandler_call
},
NULL
};
static struct RestResourcesManager_S resourcesManager =
{
&resource01, &resource01
};
The type RestResourceNode_S is defined:
struct RestResourceNode_S
{
RestResource_T resource;
struct RestResourceNode_S const *next;
}
and RestResource_t:
struct RestResource_S
{
char const *url;
int const role;
retcode_t (*handle)(Msg_T *);
};
typedef struct RestResource_S RestResource_T;

The C99 standard §6.7.8 ¶4 says
All the expressions in an initializer for an object that has static
storage duration shall be constant expressions or string literals.
Also, const are not true constants in C in the sense that they are not compile-time constant. This means that you cannot have a constant object in the initializer of a structure which has static storage allocation. However, if your structure has automatic storage allocation, this would work fine.
What you can do is define your const objects as macros -
#define resource01Url "/dummy"
#define resource01Role 2

int const does not count as a compile-time constant in C. You will have to change it to a #define instead.

Related

"Initializer element is not constant" when defining an object as a static member of a function

The following code compiles without complaints:
struct s {
const int a;
};
static const struct s *s = &(const struct s) {
.a = 5
};
int main(void) {
(void) s;
return 0;
}
However, if we move the definition of s to the body of main, i.e.:
struct s {
const int a;
};
int main(void) {
static const struct s *s = &(const struct s) {
.a = 5
};
(void) s;
return 0;
}
we get the error:
error: initializer element is not constant
static const struct s* s = &(const struct s) {
^
Since, in both cases, we deal with static (i.e. compile-time) initialization, why is the second use case illegal?
Is there any way to make it legal in the context of a function?
(I have checked this with GCC 7.3.0 and clang 6.0.0, and they both report this as an error)
Per C 2018 6.6 (“Constant expressions”) 7:
More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following: … an address constant, or…
Per 6.6 9:
An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator…
Then, in 6.5.2.5 (“Compound literals”) 5, we have:
… If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
Thus, in the first case, the compound literal is an object with static storage duration, and a pointer to it is an address constant. In the second case, the compound literal is an object with automatic storage duration, and a pointer to it is not an address constant.

How to make function pointers in a structure constant to be used to initialise a constant array? [duplicate]

This question already has answers here:
Initializing Const Struct with other Const Struct Instances
(2 answers)
Closed 7 years ago.
I have the following constant struct which holds function pointers:
/* module1.h */
typedef struct my_struct my_struct_t;
struct my_struct
{
void (*funcPtr1)(void);
void (*funcPtr2)(void);
}
extern const my_struct_t myStruct1;
/* module1.c */
#include <module1.h>
static void func1(void)
{
// do something
}
static void func2(void)
{
// do something else
}
const my_struct_t myStruct1 = {
.funcPtr1 = &func1,
.funcPtr2 = &func2
}
So far so good!
Now I want to create a constant array of the above struct and assign the function pointers from instances of the struct:
/* module2.c */
#include <module1.h>
const my_struct_t arrayOfMyStruct[] = {
{ myStruct1.funcPtr1, myStruct1.funcPtr2 },
// ...
}
Compiler throws an error and says, that the expressions "myStruct1.funcPtr1" and "myStruct1.funcPtr2" were not constant.
What is wrong?
myStruct1 is declared with the qualifier const, but it isn't constant. Static initialization requires it to be, and arrayOfMyStruct has static storage duration.
All the expressions in an initializer for an object that has static or thread storage duration
shall be constant expressions or string literals.
You can initialize it by using the functions directly: { func1, func2 },
or take the address of the pointer: { &myStruct1.funcPtr1, &myStruct1.funcPtr2 },
in which case you will have to use a different struct type for the array:
typedef struct
{
void (*const *funcPtr1)(void);
void (*const *funcPtr2)(void);
} my_struct2_t;
And syntax for calling the function has to be changed:
(*arrayOfMyStruct[0].funcPtr2)();

Initializing a struct in C : initializer element is not constant

I have read other answers on this topic, but they didn't help me.
I am trying to initalize a struct but getting the following error msgs in C:
error: initializer element is not constant
error: (near initialization for 'resource01.resource.role')
For Url it works, it's just the role which is not working. And if I'm defining the role as char, I don't have any problems. What am I doing wrong?
static char const resource01Url[] = "/dummy";
static int const resource01Role = 2;
static struct RestResourceNode_S resource01 =
{
{
resource01Url,
resource01Role,
&DummyHandler_call
},
NULL
};
static struct RestResourcesManager_S resourcesManager =
{
&resource01, &resource01
};
The type RestResourceNode_S is defined:
struct RestResourceNode_S
{
RestResource_T resource;
struct RestResourceNode_S const *next;
}
and RestResource_t:
struct RestResource_S
{
char const *url;
int const *role;
retcode_t (*handle)(Msg_T *);
};
typedef struct RestResource_S RestResource_T;
The error means that you are using a non-constant expression to initialize a structure member.
The expression is resource01Role.
While it is declared as static and const it is not an initializer constant expression from the view of the C compiler. If you want to use it this way, you would have to define it as a preprocessor macro. In your case, const only points out to the compiler that the value of resource01Role will not change - it does not permit it to use the value during compile-time.
However, as #WhozCraig pointed out, the type of role is actually int const *, so you probably meant to write &resource01Role. Adress-of is a constant expression, so that would compile.
Since resource01Url is an array, the adress-of operator & is implicitly applied by the compiler, so it is constant.

Defining a vector of struct and passing it as pointer in C - error: initialization from incompatible pointer type

I want to define a vector of struct. This vector should have the elements : user and role.
struct UserToRole_S
{
char user[SERVAL_HTTP_MAX_LEN_USER_NAME + 1];
unsigned int role;
};
typedef struct UserToRole_S UserToRole
#define ENDROLE 5
static UserToRole user_role[6] =
{
{"user5", ADMIN},
{"user4", GUEST},
{"user3", GUEST},
{"user2", GUEST},
{"user1", ADMIN},
{"andreea", ENDROLE},
};
UserToRole const *usertoroleTable[2] =
{
&user_role,
NULL
};
extern UserToRole const *usertoroleTable[];
But then I get the error: initialization from incompatible pointer type
What is wrong with my code? Definition of the vector?
You are missing typedef, you can't use the bare name of a structure as a type name in C.
Either add:
typedef struct UserToRole_S UserToRole_S;
or use:
static struct UserToRole_S user_role[] =
and so on, i.e. replace the bare name with the full struct UserToRole_S type name.

Error: initializer element is not constant - linux driver

I am really not able to solve this issue.
error: initializer element is not constant
error: (near initialization for tca6507_leds1.leds.num_leds)
I think the problem is related to struct led_info *leds inside led_platform_data. Is this somehow not a const since it is a pointer? I am particularly baffled since led_platform_data and led_info are part of the linux kernel. tca6507_platform_data is also a part of a driver that is included in the kernel source.
Here is my initialization:
static struct led_info tca6507_led_infos[] = {
{
.name = "left_blue",
.default_trigger = "heartbeat",
},
};
static struct led_platform_data tca6507_leds2 = {
.leds = tca6507_led_infos,
};
struct tca6507_platform_data tca6507_leds1 = {
.leds = tca6507_leds1
};
All the structs are defined in header files that I did not write.
struct led_info {
const char *name;
const char *default_trigger;
int flags;
};
struct led_platform_data {
int num_leds;
struct led_info *leds;
};
struct tca6507_platform_data {
struct led_platform_data leds;
#ifdef CONFIG_GPIOLIB
int gpio_base;
void (*setup)(unsigned gpio_base, unsigned ngpio);
#endif
};
The problem is right in the middle of this three line bit:
struct tca6507_platform_data tca6507_leds1 = {
.leds = tca6507_leds1
};
What is the (compile time) value of tca6507_leds1? Note that it is a structure, not an array.
Compare that with the (valid):
static struct led_platform_data tca6507_leds2 = {
.leds = tca6507_led_infos,
};
What is the (compile time) value of tca6507_led_infos? (Note that it is an array, and the "value" of an array is the address of its first element.) And most importantly (perhaps I should not have buried the lede :-) ), compare with the (also valid):
static struct led_info tca6507_led_infos[] = {
{
.name = "left_blue",
.default_trigger = "heartbeat",
},
};
Note that instead of using the value of a variable, the initializer here is a brace-enclosed list of items. This (like the failing case) is an instance of struct led_info, which must contain one actual struct led_platform_data instance (not a pointer to one-or-more, as is used in struct led_platform_data).
(The above is meant as an exercise. The answer is, the value of a structure is the value of the structure—but that is not a compile-time constant. Moreover, you are trying to use the value of the structure that you have not yet finished initializing in the first place. You need X to set X but you have to find X first, which you do by finding X, and there's no end to the recursion.)

Resources