PSTR() on __FUNCTION__

mMontu picture mMontu · Jul 31, 2013 · Viewed 11.2k times · Source

Using avr-gcc it is possible to store data on Program Memory in order to save RAM. This is acomplished using PROGMEM attribute. AVR-libc also provides a macro, PSTR(), which can be used to with literal strings.

Now I'm trying to use PSTR() with __func__, __FUNCTION__ or __PRETTY_FUNCTION__.

The following code works as expected,

display.message(__func__, 2);
display.message(__FUNCTION__, 2);
display.message(__PRETTY_FUNCTION__, 2);

, while the compilation of any of these lines fails,

display.messageP(PSTR(__func__), 2);
display.messageP(PSTR(__FUNCTION__), 2);
display.messageP(PSTR(__PRETTY_FUNCTION__), 2);

, with the following error:

initializer fails to determine size of '__c'

The definition of PSTR, from WinAVR/avr/include/avr, explains the variable referenced on the error message:

# define PSTR(s) (__extension__({static char __c[] PROGMEM = (s); &__c[0];}))

This is not something general to macros, as __FILE__ compile and work fine:

display.messageP(PSTR(__FILE__), 2);

Any ideas on what is causing this error, and if it possible to use PSTR() to insert function name on program memory?

Answer

jxh picture jxh · Jul 31, 2013

__func__, __FUNCTION__ and __PRETTY_FUNCTION__ are not string literals, like __FILE__, but are created like static local char array variables to the function you are using them from. So, the PSTR() macro will fail since you cannot use an array variable to initialize another array variable like that.

__func__ is described in C11, §6.4.2.2 ¶1:

The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

static const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function.

According to the GCC manual, __FUNCTION__ and __PRETTY_FUNCTION__ are just synonyms for __func__ in C (__PRETTY_FUNCTION__ is more verbose for C++).