I have encountered a C++ issue that I am seeking some advice on. For the arm architecture, I can declare a const, specifically a character string, in one translation unit (file) and ensure that the const is put into flash memory. However, I cannot access the const from another translation unit. Here is an example.
The following declaration will create a constant character string "hello" and it will be located in flash memory:
file1.h:
const char str[] = "hello";
To access the variable name from another translation unit, I try to use extern as follows:
file2.h:
extern const char * str;
However, this generates an error indicating that the declarations are different:
Then the variable cannot be accessed outside of the scope it was declared in (because of the static keyword).
So, I cannot find the correct way to access a const stored in flash from another translation unit. Does anyone have any suggestions regarding how to do so?
sslupsky:
I still get the error. The compiler is complaining that the two definitions are conflicting:
const char str[] vs const char * str
The definitions ARE conflicting. In one place you say 'str' it the address of the first character in an array of characters and in the other you say that 'str' is the address of a pointer that contains the address of a character. They are not the same thing and thus you can't have the name declared both ways at the same time.
Thanks. I had earlier tried the opposite combination but that doesn't put the string into flash memory.
Reversing it, as you showed, solved the problem. I thought I did that at one point but I must have had another issue and mistakenly thought it didn't solve the problem.
You are exactly correct, which is why I was scratching my head on this one. @Juraj helped me get my thinking straight on this and resolved it.
Thanks for taking the time to provide some feedback.
I do have one other conundrum. I am trying to determine if the strings in the following struct are stored in flash memory or not with the following declaration:
I used the nm tool to look at the memory but I cannot find anything resembling any of the names used so I cannot tell. Does this look correct to you? My suspicion is they are not.
what MCU is it? on AVR and esp you must use the PROGMEM macro to put the strings in macro and on you must handle the progmem strings with dedicated functions
on AMR (SAM(D), nRF5) architectures there is no special progmem string handling
const char * yetAnotherString = "Yet Another String";
does not cause the string to be located in flash.
Moreover, the form const char someString[] when in the global namespace puts the string into global flash. What I think I am seeing with the struct{} is that even if the struct{} is defined const in the global namespace, when you use a struct member it in a member function, the string is allocated to flash local to the member. So, if the same string is used in multiple places, it is replicated in flash multiple times within the flash for each member function that uses it.
I would like to direct the compiler to store the strings within the struct to be located in global flash.
btw: it is not about 'putting' in flash or not. they are there as part of the application. it is about using them from flash without loading them to RAM at start
Agreed, "putting" is probably the wrong way to describe it.
I think I have been able to confirm that the strings within the global struct{} are being store in global flash. For some reason the global struct{} does not appear in the nm output so it is difficult to discern where the strings were put and if there are any pointers in ram referencing the strings.