2

I'm working in C on an embedded microcontroller and am attempting to declare and initialize (in ROM) a const struct with an array of const structs, as demonstrated by this extremely simplified example:

typedef struct s_test TestStruct;
struct s_test {
   char c;
   int const * const ptr;
};

TestStruct const test1 = { 'a', NULL };

TestStruct const test2 = { 'a', (const int const []){ 2, 3, NULL } };

Instance test1 occupies ROM as expected, while in the case of instance test2, the child array ends up in RAM (not ROM, as intended).

If I declare an intermediate array, then use the reference to that array, the structure and array instances occupy ROM as expected...

int const array1[] = { 1, 2, NULL };

TestStruct const test3 = { '1', array1 };

Why, when I declare and initialize the array within the structure initialization, does the child array get stored in RAM instead of ROM? Perhaps my syntax is incorrect? Is there a successful way to do this? It would make for so much more readable data structure declaration and initialization, rather than having to forward-declare all the intermediate child arrays. Initially I thought I was so clever declaring my data structure, but then was sorely disappointed to find it was largely occupying RAM. :\

2
  • Did you try struct s_test {char c; int list[];}, so that the list is contiguous with the struct? Commented Jun 18, 2014 at 7:08
  • Good suggestion, and that does work for this example, BUT unfortunately I may have simplified this example too much. In my code, that last member is a pointer to a struct of the same type as the containing struct (s_test in this example case). So I can't use the Flexible Array Member feature, as the compiler gives a "array type has incomplete element type" error. Commented Jun 18, 2014 at 23:17

1 Answer 1

2

The word const doesn't mean that the value is stored in ROM, it means that the value is not supposed to change after it is initialized. You can have objects in RAM that are const. The compile can decide whether or not to put into ROM, depending on the optimizer trying to save RAM, but there is nothing that guarantees it. Casting something to const is even weaker. Your {2,3,NULL} is not const when created.

You need to read the manual for your compiler and figure out how to place objects into ROM (or probably Flash memory). Some compilers have a keyword to do this, like code or __rom that you use instead of const.

The alternative is to create a new "section" in the linker file, and place all your ROM variables in that section.

There is no standard way of doing it unfortunately.

Sign up to request clarification or add additional context in comments.

3 Comments

To add the formal wording: It's is "implementation defined" where the read-only objects are placed.
Thanks for the info Mark. Yes, 'ROM' physically means Flash. As for my compiler options, there is an option -mconst-in-code which supposedly forces const declarations into ROM (the default), but it does not seem to affect this declaration. Also, using a "section" attribute does not seem to be an option due to the limitations in the way the uC addresses code-space.
Oh, and yes I did realize that casting with 'const' is weak... it makes no difference. So, overall the compiler seems to ignore the normal rules for this inline declaration, and places it in RAM no matter what.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.