avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] C++ with PSTR


From: Paul Stoffregen
Subject: Re: [avr-gcc-list] C++ with PSTR
Date: Mon, 07 Dec 2009 01:55:28 -0800
User-agent: Thunderbird 2.0.0.23 (X11/20090817)

I have a perhaps related question. It is possible to test at compile time if a variable is a string literal, so I could have a macro that automatically embeds the PSTR() and _P stuff, but also works with normal arrays?

For example, I often use this.

#define print(s) print_P(PSTR(s))

It's nice to just write print("something"). Of course, it only works if the something is a string literal.

Maybe some combination of __builtin_types_compatible_p or _built_const_p or typeof? I tried playing with these but could never seem to make a macro that resolves one way if the arg is a string literal and another way if it's a pointer or anything else.


-Paul



Dave Hylands wrote:
Hi,

On Sun, Dec 6, 2009 at 4:20 AM, darkschine <address@hidden> wrote:
This topic is covered all over avr forums in bits and pieces so please keep
responses to a minimum. The problem is that when using PSTR("String") in a
cpp file, the compiler generates the warning:

warning: only initialized variables can be placed into program memory area
...snip...

Does anyone have a proven solution or workaround for this problem? Is there
anything that can be done to at least suppress the warning without
suppressing other warnings?

I think I found a way.

I tested this with WinAVR-20080610 (gcc 4.3.0) and with the latest
(WinAVR-20090313 gcc 4.3.2).

My source file, called test.cpp was as follows:

----- Start of test.cpp -----
#include <avr/pgmspace.h>

#if 0
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))

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

void Log_P( const char *fmt, ... );

void foo( void )
{
    Log_P( PSTR( "foo was called\n" ));
}
----- End of test.cpp -----

As shown above, I compiled it with the following command line:

603 >avr-g++ -mmcu=atmega168 -c test.cpp -o test1.o
test.cpp: In function 'void foo()':
test.cpp:15: warning: only initialized variables can be placed into
program memory area

and then ran

604 >avr-objdump --full-contents test1.o

test1.o:     file format elf32-avr

Contents of section .text:
 0000 df93cf93 cdb7deb7 80e090e0 00d0edb7  ................
 0010 feb73196 91838083 0e940000 0f900f90  ..1.............
 0020 cf91df91 0895                        ......
Contents of section .progmem.data:
 0000 666f6f20 77617320 63616c6c 65640a00  foo was called..

I then changed the #if 0 to #if 1 and repeated, replacing test1.o with test2.o

605 >avr-g++ -mmcu=atmega168 -c test.cpp -o test2.o
606 >avr-objdump --full-contents test2.o

test2.o:     file format elf32-avr

Contents of section .text:
 0000 df93cf93 cdb7deb7 80e090e0 00d0edb7  ................
 0010 feb73196 91838083 0e940000 0f900f90  ..1.............
 0020 cf91df91 0895                        ......
Contents of section .progmem.data:
 0000 666f6f20 77617320 63616c6c 65640a00  foo was called..

607 >cmp test1.o test2.o

shows that the two objects are in fact 100% identical, but the 2nd
version has no warning.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]