Very good find! Thanks.
But, I just did some checking, and moving that keyword changes the memory usage by 6 bytes, which is the size of the pointers (three 2 byte pointers). I think placing it there is just placing those pointers in RAM, like not having PROGMEM at all, which explains why it works. (I just did a test. Same free RAM by not using PROGMEM.)
But I do believe this is a compiler thing. In my working code, I just retrieve the address using pgm_read_word() and pass that in:
Serial.println((__FlashStringHelper*)pgm_read_word(flashArray+i));
But, if this one thing gets fixed to work consistently, I want to go to doing something like this:
#ifdef USE_FLASH
#define FLASHSTR PROGMEM
#define FLASHCAST const __FileStringHelper*
#else
#define FLASHSTR
#define FLASHCAST char *
#endif
It's not quite flexible enough yet, but it allows me to have code that conditionally compiles to either put the strings in RAM (using FLASHSTR where we use PROGMEM now) or in Flash just by adding "#define USE_FLASH".
If I have the RAM to spare, I'd rather use it and save some clock cycles. But, if I get to the point where RAM is more important, then I can enable that #define and everything magically switches. I am doing that now, but I had to put more code in and #ifdef things that should work with the casting alone, so they either use char* or pgm_read_work(). It works, but is a bit more to maintain.
Thanks for that thread -- I will bookmark it.
And some other tidbit... The prototypes are sometimes required to work around what may be another bug. I had a specific problem with an error saying a function of mine was being redeclared differently, even though it was only used once, and matched parameters exactly with the declaration in the same file. Adding the prototype allowed it to compile. I'm pulling my hair out over these things
But ... it's great stuff, and the tools are free, and I am the last person to complain about free!
Thanks so much for the pointers!