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.
Related
This question already has answers here:
typedef pointer const weirdness
(6 answers)
Closed 8 years ago.
I have a struct type_s. Then I typedef a pointer to a struct type_s as type.
If I have a const struct type_s* then the compiler will correctly complain if an assignment is made to the struct member, as seen in function Test1(). But if I make a const type, which is a typedef for the same struct pointer the compiler will not complain and compile, function Test2().
typedef struct type_s* type ;
struct type_s
{
int a ;
} ;
void Test1( const struct type_s* t )
{
t->a = 123 ; //complains, ok
}
void Test2( const type t )
{
t->a = 123 ; //doesn't, it should in my oppinion
}
To me they are logically both the same thing. What am I missing?
Is the only solution to create another typedef for a constant pointer to that struct like this:
typedef const struct type_s* ctype ;
which will work correctly as in Test1().
What you're missing is that a const pointer is not the same thing as a pointer to a const object. You have one of each. A const pointer is a pointer whose stored address is not modifiable; a pointer to const is one which cannot be used to modify its referent.
They are not the same thing. const has different semantics when applied to the definition or declaration of a pointer variable and a non-pointer variable.
const struct type_s *t
The above statement defines t to be a pointer to an object of type const struct type_s. Here, const qualifies the type struct type_s of the object t points to, not the pointer t.
typedef struct type_s *type ;
The above statement defines an alias named type for the type struct type_s *.
const type t;
// equivalent to
type const t;
// equivalent to
struct type_s *const t;
The above statement defines t to be a constant object of type type. Here const qualifies the object. You cannot replace the typedef with its original type and reinterpret it as if it were a macro. The pointer information is embedded in the typedef and it will be treated as a non-pointer type.
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.
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.
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.)
Can someone tell me the difference between these two versions of a declaration of a structure?
struct S
{
uint8_t a;
};
and
const struct S
{
uint8_t a;
}
Followed by:
void main(void)
{
struct S s = {1};
s.a++;
}
Hint, i've tried both versions for S in Visual Studio C++ 2010 Express so I know that both compile with errors.
Is the "const struct" doing nothing at all? "const struct S s = {1};" certainly does, but that's not the issue at the moment.
Regards
Rich
/********************************************/
I've just worked out what
const struct <typename> <{type}> <variable instances a, b, .., z>;
is doing:
When const is present before the "struct", all variable instances are const, as though they'd be defined with:
const struct <typename> a, b, z;
So it does do something, but not when there's no instance definitions in-line with the struct declaration.
Rich
A declaration of structure just defines the data type.
const qualifier appies to a variable not a data type. So adding const preceeding a struct declaration should be redundant at the most.
With:
const struct S
{
uint8_t a;
};
The const qualifier there is nonsense, and may even cause a compilation error with some C compilers. gcc issues a warning.
The intent appears to be to declare the data type struct S. In this case, the proper syntax is:
struct S
{
uint8_t a;
};
const struct S
{
uint8_t a;
};
is not a valid construct.
This
const struct S
{
uint8_t a;
} x;
could possibly be valid as you're declaring a variable x that is now const, meaning it cannot change.
The const qualifier applies to variables or members.
To instantiate a const variable, just specify const during instantiation.
What const does, is:
during compilation, verify that only reads are performed on the const variables
if the const variable is created with a value which can be resolved during compilation, put the variable in the program memory
When const is applied to members, like in:
struct T {
int const i;
int j;
};
You can only (legally) assign the value i during the creation of the structure.
You may be able to modify a const value (if the program memory sits in RAM and not ROM) by casting it to a non-const type (const-cast) but this is something you shouldn't do.
The typical usage of const-cast is when you use a library which does not specify the constness in function declarations, and your code does. At this point if you want to use it you have to trust it and cast parameters before calling its functions.
It is nonsense to use const keyword before struct.
If you are using gcc compiler, it shows you the following warning:
warning: useless type qualifier in empty declaration [enabled by default]
This is the only use I can think of:
const struct S {
int a;
int b;
} s;
This declares a struct and immediately creates an instance for it named s and at this point, a and b in s are initialized to 0 (please note that at this point s is a global variable in the translation unit which it has been declared in and can be externally linked to).
printf("a = %d\t b = %d\n", s.a, s.b); // a = 0 b = 0
If you try to set members of s, you will fail:
s.a = 1; //error: assignment of member ‘a’ in read-only object
So, s is not really useful here...unless you do something like:
const struct S {
int a;
int b;
} s = { 1, 2 };
Now let's create another instance of the same struct (declaration is still same as above):
struct S other;
other.a = 1;
other.b = 2;
printf("a = %d\t b = %d\n", other.a, other.b); // a = 1 b = 2
The compiler will not complain anymore as other is not const! only s is const!
Now, what that const do, you may ask? let's try to change s:
s = other; // error: assignment of read-only variable ‘s’
That is all to it. If you did not need the compiler to allocate storage for s at the point of declaration and still needed an instance of s to be const you would just add const at the point of instantiating struct S (note the capital S!!)
Bonus 1
const struct S {
int a;
int b;
};
note that there is no small s anymore. At this point, GCC will warn you that const qualifier does not do anything!!!!
Bonus 2
If you want every instance of the struct to be const, that is its members can only be initialized at the point of definition you can do like (using typedef):
typedef const struct S {
int a;
int b;
} s;
// The wrong way
s thisIsAnS;
thisIsAnS.a = 1; //error: assignment of member ‘a’ in read-only object
// The correct way
s thisIsAnS = { 1 , 2 }; //compiles fine, but you can not change a or b anymore
Conclusion
To me, this is just syntactic sugar and only adds unnecessary complexity to the code. But who am I to judge...
When you declare
const var;
then it allocate the some memory space for it but
struct var;
it was just an declaration compiler does not allocate any space for it.
so it shows the error and in const struct you didn't declare any varible see the code so it shows error.