0

I'm trying to initialize a struct with values passed as function arguments, as follows:

struct my add(uint16_t x, uint16_t y, const char *text, uint8_t b, uint8_t c)
{
    struct my M =
    { x, y, NULL, NULL, text, b, NULL, NULL, c, NULL, NULL};
    array[count] = my;
    count++;

}

However, on the line with struct initialization, I get:

#28 expression must have a constant value

How else do I achieve it, without getting this error?

Michał Szydłowski
  • 3,261
  • 5
  • 33
  • 55
  • You already have a worst problem, `widgets` and `widget_count` are global, which means there might be some other design problems. Why don't you just make a struct containing a list of `struct widget` objects or an array containing the array size? and then write some accessor functions to initialize the struct correctly. – Iharob Al Asimi Mar 27 '15 at 12:08
  • 2
    possible duplicate of [Error 28: Expression must have a constant value](http://stackoverflow.com/questions/24528084/error-28-expression-must-have-a-constant-value) – ecatmur Mar 27 '15 at 12:09
  • array containing the array size - could you explain? Right now I have `struct widget widgets[50]` – Michał Szydłowski Mar 27 '15 at 12:11
  • What compiler are you using? – Mgetz Mar 27 '15 at 12:11
  • @MichałSzydłowski probably, that could work, still your initialization is realy ugly. You can use `memset()`. – Iharob Al Asimi Mar 27 '15 at 12:11
  • I'm using ARM compiler, it's an embedded project – Michał Szydłowski Mar 27 '15 at 12:12
  • 1
    Why do you initialise integers with the `NULL`-pointer value? – alk Mar 27 '15 at 12:13
  • @alk right, didn't notice that because that initialization is hard to look at ... now my `memset()` suggestion makes more sense. – Iharob Al Asimi Mar 27 '15 at 12:15
  • possible duplicate of [Error "initializer element is not constant" when trying to initialize variable with const](http://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w) – Toby Mar 27 '15 at 12:20
  • Dubplicate: http://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w – Toby Mar 27 '15 at 12:20
  • Please post `struct my` definition. – chux - Reinstate Monica Apr 21 '15 at 18:06
  • The problem is solved, @iharob 's answer turned out to work nice. – Michał Szydłowski Apr 21 '15 at 20:08

2 Answers2

1

The most important problem I see is that you are assigning the text pointer to your struct's text pointer, which is most likely wrong since the text field is not const.

Removing the const from the parameter could also be wrong, adding it to the struct field could be Ok if you ensure that the contents pointed to by this pointer will remain valid through out the life of the struct instance.

What you are trying to do is a lot cleaner if you just memset(&widget, 0, sizeof(widget))1 and then initialize each field like this

struct widget instance;
memset(&instance, 0, sizeof(instance));

instance.x    = x;
instance.y    = y;
instance.text = malloc(1 + text_size);
if (instance.text != NULL)
    strcpy(instance.text, text);
instance.text_size = text_size;
instance.text_font = text_font;

and then the

widgets[widget_count++] = instance;

part, should not go in that function, that function should just

return instance;

wherever you allocated the widgets array manipulate both the array and the widget_count variable, don't make them global just to be able to access them from another function, if you must access them from another function pass them as parameters, if you have to modify widget_count in another function pass it's address as a paramter.

But the way you have it, the context is not clear, so you might end up doing very bad things when the code gets more complex.


1You need to include string.h in order to use memset() and strcpy()

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • Maybe, if `text` the passed pointer, is not a static literal string allocated in the stack frame of a function that will return and then the data will be deallocated leading to Undefined Behavior, you should also make the `text` field `const` and be sure that the described probelm will not happen, with the code posted in your question it's not possible to tell you if it's ok to just assign the pointer, it could be ... you need to learn about poitners I think. – Iharob Al Asimi Mar 27 '15 at 12:24
  • But I ask again - HOW can I modify a field that is `const`? – Michał Szydłowski Mar 27 '15 at 12:27
  • Oh, I see ... you don't want to modify it, you will assign to it, it's not the same, the contents are `const` the pointer is not in this `const char *pointer;` you can make `pointer` point wherever you want, but you cant alter the pointed to content. This `const char *const pointer;` makes both `const`, the pointer and the pointed to data. If you want to alter the pointee, then you **must** copy the data. – Iharob Al Asimi Mar 27 '15 at 12:34
1

I'd say the compiler complains that you are try to initialise a non-const member of a struct (char *text) with a const value (const char *text) as being passed in.

To get around this either remove the const from the argument's definition or define the struct's member to be const.

alk
  • 69,737
  • 10
  • 105
  • 255