5

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?

Community
  • 1
  • 1
mMontu
  • 8,983
  • 4
  • 38
  • 53
  • Looks like those string literals cannot be placed in that space as they require special functions? to access them. In truth, these names should be pretty darn small so I wonder if there is a real advantage to moving them there anyways. I say this with no idea of the actual amount of RAM you have though. – Michael Dorgan Jul 31 '13 at 17:02
  • @MichaelDorgan avr-libc provide functions to access variable in program memory; this is confirmed by the last line of code on the question, which works fine. I agree that these strings are small, but they are significant in embedded systems (with only a few Kbytes of RAM). – mMontu Jul 31 '13 at 17:50

1 Answers1

8

__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++).

jxh
  • 69,070
  • 8
  • 110
  • 193
  • Is there a way to get __func__ into program memory? By default the definition places it in RAM. Obviously people don't want to waste RAM on static debugging data. –  Nov 05 '14 at 10:39
  • The question was about avr-gcc, implying the AVR platform. It is a Harvard architecture with two memory spaces. Program memory is the device's flash memory, normally read-only. Since the devices only have limited RAM (16k is about the limit, typically 2-4k) you don't want to fill it with debug strings. –  Nov 05 '14 at 23:58
  • @MoJo: Thanks, for the clarification. It seems you will need to declare you own variables on a case by case basis if you have this requirement, or you have to modify the compiler to extend it to allow you to specify the memory target for the `__func__` variable. – jxh Nov 06 '14 at 00:24
  • I put in an enhancement request for GCC. –  Nov 06 '14 at 11:48