How to use F() in static initialization?

I have code like this

struct IdName {
  const uint8 id;
  const char *name;  
};

const  IdName kIdNames[] = {
  { 1,  "foo" },
  { 120,  "bar" }  
};

My understanding is that the string literals occupy RAM space (scarce) so I would like to move them into flash space using F(). I tried this but got a compilation error: "error: statement-expressions are not allowed outside functions nor in template-argument lists"

struct IdName {
  const uint8 id;
  const __FlashStringHelper *name;  
};

const  IdName kIdNames[] = {
  { 1,  F"foo") },
  { 120,  F("bar") }  
};

Any suggestion how to make it to work?

I have not tried to do what you are attempting. However, I have done something similar. What I have done is something like this:

  switch ( Command ) {
    case 1): cmd = (PGM_P) F("Down");   break;
    case 2): cmd = (PGM_P) F("Left");   break;
    case 3): cmd = (PGM_P) F("Right");  break;
    case 4): cmd = (PGM_P) F("Up");     break;
    default: cmd = (PGM_P) F("Unkown"); break;
  }
  strcpy_P(ptr, cmd);

You may be able to just cast the F() constant. You will need to use the "_P" functions to access the values.

I would do this instead:

PROGMEM prog_char up[]="Up";
PROGMEM prog_char down[]="Down";
PROGMEM prog_char Left[]="Left";
PROGMEM prog_char Right[]="Right";
PROGMEM prog_char Unknown[]="Unknown";

//setup() and loop()

  switch ( Command ) {
    case 1: cmd = Down;   break;
    case 2: cmd = Left;   break;
    case 3: cmd = Right;  break;
    case 4: cmd = Up;     break;
    default: cmd = Unkown; break;
  }
  strcpy_P(ptr, cmd);

I think this way if you use these string literals elsewhere in your code, you are not duplicating them in the PROGMEM (FLASH). F() doesn't optimize duplicate strings but you can.

zapta:
My understanding is that the string literals occupy RAM space (scarce) so I would like to move them into flash space using F(). I tried this but got a compilation error: "error: statement-expressions are not allowed outside functions nor in template-argument lists"

Easy.

void setup (void)
{
    Serial.begin (115200);
    uint8_t x;
    const char *messages[] = {
        PSTR ("Up"),
        PSTR ("Down"),
        PSTR ("Right"),
        PSTR ("Left") 
    };

    for (x = 0; x < 4; x++) {
        Serial.println_P (messages[x]);
    }
}
void loop (void)
{
}

Where does the .print_P() come from? I'm curious. I looked at arduino ide 1.0.5 and didn't find this function.

Thanks everybody for the info. I ended putting the entire array of structs in flash and reading pieces of it to ram as needed. Here is the actual snippet from my program. For efficiency I read the two fields independently I I also tried memcpy one struct at a time from flash to ram and it worked.

struct BitName {
  uint8 mask;    // 1 byte
  char *name;    // 1 word
};

static const  BitName kErrorBitNames[] PROGMEM = {
  { ERROR_FRAME_TOO_SHORT, "SHRT" },
  { ERROR_FRAME_TOO_LONG, "LONG" },
  { ERROR_START_BIT, "STRT" },
  { ERROR_STOP_BIT, "STOP" },
  { ERROR_SYNC_BYTE, "SYNC" },
  { ERROR_BUFFER_OVERRUN, "OVRN" },
  { ERROR_OTHER, "OTHR" },
};

static void printErrors(uint8 errors) {
  const uint8 n = sizeof(kErrorBitNames) / sizeof(kErrorBitNames[0]);
  for (uint8 i = 0; i < n; i++) {
    const uint8 mask = pgm_read_byte(&kErrorBitNames[i].mask);   // <<-- reading first field
    if (errors & mask) {
      const char* const name = (const char*)pgm_read_word(&kErrorBitNames[i].name);  // <<-- second field
      sio::print(name);
    }
  }
}

liudr:
I think this way if you use these string literals elsewhere in your code, you are not duplicating them in the PROGMEM (FLASH). F() doesn't optimize duplicate strings but you can.

Yes, PROGMEM did the trick for me. In the example you posted, you could have a PROGMEM array of the strings instead of individual strings. This way you can lookup the command using index instead of a switch statement.

Try prog_char* or PGM_P instead of char*

Good for housekeeping.