Here is a full example. The main for loop works and properly prints the strings. But, if you uncomment the "//Serial.println()" in thisFails(), it starts printing garbage.

The duplicate print in "thisFails()" is what I was trying to do, but I have yet to get it to work. Simply having a Serial.println() causing it to not work clues me in that it may just be another oddity with the compiler preprocessor.

void thisFails(int i){ // Uncomment out the next line, and it stops working. //Serial.println("Comment this line out and it works.");

// This is the line I want to work, but it always fails. BUT, // if you manually pass a number in to the flashArray[0], it // works, or if you set "i=0;" before it, it works. Weird. //Serial.println((__FlashStringHelper*)flashArray[i]);}

Yes, I actually found that thread before when first researching PROGMEM. It is a very good one.

But this is actually a compiler question, not a PROGMEM question. My question here is what is the compiler doing to change things just by calling a Serial.println(). It's the third issue I have ran in to, with the last two being bugs requiring workarounds, and I am wondering if this is another one.

Looking at the source in Print.cpp, I see it has one that expects a "const __FlashSTringHelper *" and I am specifically casting to that. It looks like something may be trashing the stack or, perhaps, the preprocessor is misreading the source and changing the casting based on what it sees in the source code when that is there. (I am leaning to this second explanation, based on previous issues I have run in to.)

Thanks, SurferTim. I actually have all of this working fine in my production code. I just noticed some very odd things and created this small example to replicate the problem.

With that array in PROGMEM, I have 1839 bytes free on my test program. With PROGMEM removed, it goes to 1833 bytes. The 6 bytes different is because each of those is a 2-byte pointer, so that makes sense. In my production code, I have a much much larger array of strings, and I am down to about 200 bytes free, so every little bit counts, which is what has me converting everything over to Flash storage right now.

It's just a weird thing. Everything works just fine, until code is added around it, then it breaks. I thought it had to do with the function() I was calling, but after I eliminated that I could break it without anything -- just by adding a "delay(1);" or similar around it.

I should probably learn how to read reported bugs, and how to submit ones I can't find already submitted.

I apologize, that I spoke too soon. It is a bug/problem of the gcc compiler.

It has to do with the PROGMEM. http://www.arduino.cc/en/Reference/PROGMEMIt says: "However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another".

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:

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 for noticing that. I only checked the flash size and didn't check the ram size.I tried a few more tests, and did some "avr-objdump -d" on the object file, but that didn't make things clear for me.

Serial.println((_FlashStringHelper*) ( optCmd[i]) ) ;I'd have to dig into docs to figure out if the extra parens are necessary, and think WAY to hard to figure out why it worked for the case with the constant 0 index, but I think the behavior is consistent with getting the cast vs array index order of operations wrong.

westfw, no change on the parens. I really believe it's a compiler issue. It works fine, 100% of the time, with just the call, but place something else around it, and it stops working. When I got down to just doing a "delay(1);" and it broke, I pretty much gave up.

I developed my own routines for handling these items when I ported an old program that expected 21,000 bytes of RAM to work on the Arduino's 2K (just an impractical amount of array storage to be useful), but I really thought I could simplify things once I found that all the Print:: functions were already handling __FlashStringStorage* (so why do it twice).