Re: Can't use F() at global scope

You can pass a "const PROGMEM char*" to a function. I haven't tried it in a class, but this works.

const PROGMEM char pgmBuf[] = "testing";
char tBuf[sizeof(pgmBuf)];

void printMe(const PROGMEM char* testProg) {
  strcpy_P(tBuf,testProg);
  Serial.println(tBuf);
}


void setup() {
  Serial.begin(115200);
  printMe(pgmBuf);
}

void loop() {
}

edit: You can put tBuf in the printMe function if you know the max size of the flash string. That way the tBuf array memory is allocated only when the printMe function is called, and released when it exits.

By the way, I'm not married to the idea of using __FlashStringHelper. If there's a better way to do what I'm trying to do (create instances of objects with constant strings in PROGMEM) then I'm all ears.

Two choices: PROGMEM or __FlashStringHelper. If variable is defined with PROGMEM/__FlashStringHelper and parameter is required opposite __FlashStringHelper/PROGMEM you have to use reinterpret_cast to avoid instruction overhead. You can use both types of function in program: Serial.print like and also printf_P like.

If FPSTR macro is not defined, define it as following:

#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))

At global scope use:

static const char flashString[] PROGMEM = "This String Compiles";
MyClass foobar (FPSTR(flashString));

I think it's easier to make the PSTR use a lambda expression instead of compiler extensions. This allows you to use it at global scope:

PieterP:
The default PSTR macro (program memory string) uses exotic compiler extensions, so you can't use them outside of functions, but luckily, you can circumvent this using a lambda expression:

#undef PSTR
#define PSTR(s) ([]{ static const char c[] PROGMEM = (s); return &c[0]; }())

const auto foo = F("I am a string in PROGMEM");
const auto bar = "I am a string in RAM";

The type of "foo" will be "const __FlashStringHelper * const" in this case.

Pieter

This works in global scope:

const char foobarString[] PROGMEM = "This String Won't Compile";
MyClass foobar ((__FlashStringHelper *)foobarString);

Results on an UNO:

myStr = This String CompilesmyStr = This String Won't Compile

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.