How do I get rid of "PROGMEM" warnings

I am getting warning when I use PROGMEM. I want to make sure I am using it correctly so I copied this simple test script out of the Playgound.

#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0";
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";
const char *string_table[] PROGMEM = {string_0,  string_1,  string_2,  string_3,  string_4,  string_5};
char buffer[30];    // make sure this is large enough for the largest string it must hold

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < 6; i++) { // Necessary casts and dereferencing, just copy. 
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); 
    Serial.println(buffer);
    delay( 500 );
  }
}

When I compile it get the following warnings. I thought I was correctly using the PROGMEM parameter. I tried moving it around in the statement but I still get the warning. How do I fix this problem?

PROGMEM_Test.cpp:5: warning: only initialized variables can be placed into program memory area
PROGMEM_Test.cpp:6: warning: only initialized variables can be placed into program memory area
PROGMEM_Test.cpp:7: warning: only initialized variables can be placed into program memory area
PROGMEM_Test.cpp:8: warning: only initialized variables can be placed into program memory area
PROGMEM_Test.cpp:9: warning: only initialized variables can be placed into program memory area
PROGMEM_Test.cpp:10: warning: only initialized variables can be placed into program memory area
PROGMEM_Test.cpp:11: warning: only initialized variables can be placed into program memory area

Also, when it says "PROGMEM_Test.cpp:5: ..." I assumed that to mean program/sketch PROGMEM_Test.cpp line 5. However this is clearly not the case. The first PROGMEM is on line 2. What is with this?

If you look at the file which is actually compiled the IDE has added a couple of lines:

#include <avr/pgmspace.h>
#include "Arduino.h"
void setup();
void loop();
prog_char string_0[] PROGMEM = "String 0";
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";
const char *string_table[] PROGMEM = {string_0,  string_1,  string_2,  string_3,  string_4,  string_5};
char buffer[30];    // make sure this is large enough for the largest string it must hold

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < 6; i++) { // Necessary casts and dereferencing, just copy. 
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); 
    Serial.println(buffer);
    delay( 500 );
  }
}

Now your PROGMEM is on line 5.

See: 34734 – [4.2/4.3/4.5/4.6 Regression][avr] attribute((progmem)) not handled properly in C++

It is claimed:

Known to work: 4.6.2

Personally I have: avr-gcc (GCC) 4.3.3

I don't know how to get 4.6.2, but if you can that might fix it.

I am using the Arduino IDE 1.0.1 and it comes with avr-g++.exe (gcc version 4.3.2). I have no idea how I would change that.

So it sounds like the answer is "Live With It". I hate doing that but if I have no choice, I have no choice.

This thread has a solution:
http://arduino.cc/forum/index.php/topic,102182.0.html

Pete

el_supremo:
This thread has a solution:
http://arduino.cc/forum/index.php/topic,102182.0.html

Pete

That is an interesting thread but I am not using the "FlashStringHelper" F().

The fix in that link has removed all warnings for PROGMEM and F() in my code. But ...
I tried your program and it generates a compiler error. So I removed the mod to WString.h from that thread and now it compiles (with the warning messages).
Looks like the fix here http://arduino.cc/forum/index.php/topic,102182.0.html doesn't always work.

Pete

RandallR:
I have no idea how I would change that.

Me neither.

So it sounds like the answer is "Live With It". I hate doing that but if I have no choice, I have no choice.

This is one of the flakier parts of the IDE. First, warnings aren't on by default. Second, if you enable verbose output you get a lot of other junk. Plus warnings. Including these bogus ones.

Bear in mind they are "just" warnings. You could try to filter them out, either mentally or another way.

4.6.2 definitely fixes it. 4.7.0 works great, too. SprinterSB puts up 4.7.0 for windows at http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=115337

The problem is a warning is called a "Warning" for a reason. Errors are easy, there is definitely a problem. Information messages are nice to know. But warning need to be investigated, there MAY be a problem. And there should be a way to remove the warning once it has been investigated.

It's like, if you are compare a signed and unsigned number. They have different ranges of values so the comparison could cause a problem. If you look at your code and you see that this will not cause a problem then cast one of the numbers and the warning goes away. You are able to use the computer to warn you of potential problems and make you code better.

I feel ignoring warning messages is a waste of resources. My "rule of thumb" is that code should always compile without warnings. But that's just me.

RandallR:
I feel ignoring warning messages is a waste of resources. My "rule of thumb" is that code should always compile without warnings. But that's just me.

I agree with you. But when the warning is wrong, that is different. Of course, the bad warning should be fixed.

Plenty of times we have seen problems from people where, if warnings had been enabled, the warning would have pointed to the problem.

The simple answer: declare the variables "extern" with the datatypes outlined in pgmspace.h before you define them normally.

A happy shout out to MegaTorr on avrfreaks (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=57011)
where he said way back in 2008: "When the initialization goes along with the declaration C++ issues the warning, when declaration and definition/initialization are separated C++ has no issues. "

What would it take to change the code at PROGMEM - Arduino Reference to the following:

#include <avr/pgmspace.h>

extern prog_char string_0[] PROGMEM;
extern prog_char string_1[] PROGMEM;
extern prog_char string_2[] PROGMEM;
extern prog_char string_3[] PROGMEM;
extern prog_char string_4[] PROGMEM;
extern prog_char string_5[] PROGMEM;

char string_0[] = "String 0";   // "String 0" etc are strings to store - change to suit.
char string_1[] = "String 1";
char string_2[] = "String 2";
char string_3[] = "String 3";
char string_4[] = "String 4";
char string_5[] = "String 5";

// Then set up a table to refer to your strings.
extern PROGMEM const char *string_table[] ;	   // change "string_table" name to suit
const char *string_table[] = 	   
{   
  string_0,
  string_1,
  string_2,
  string_3,
  string_4,
  string_5 };

...