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

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

[avr-gcc-list] Re: invalid use of non-lvalue array


From: René Liebscher
Subject: [avr-gcc-list] Re: invalid use of non-lvalue array
Date: Tue, 20 Apr 2004 12:43:43 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.6) Gecko/20040114

Is this problem solved? (PSTR with C++)

I tried to change the PSTR macro to work around the problem.

It was

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

after changing it to

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

it seems to work.
Maybe someone could check this, so it can be fixed in next versions of
avr-libc?

Kind regards
Rene Liebscher

On Wed, 1 Oct 2003, E.Weddington wrote:

> I am trying to use avrgcc for a little bit of C++ and it seems
> that the trusty PSTR macro isn't so trusty when using C++ giving
> an error of "invalid use of non-lvalue array".
>
> Before I dive into it I wonder if anyone else out there has solved
> this one?


If you're using C++, be sure to read the FAQ:
<http://savannah.nongnu.org/download/avr-libc/doc/avr-libc-user-manual/FAQ.html#faq_cplusplus>

Also, avr-gcc.exe is the C compiler. You'll want to use avr-g++.exe
which is the C++ compiler.

I don't think that addresses the problem.

I can easily reproduce this. The only way I could work around it was
with this hack:

-- begin example --
#include <stdio.h>
#include <avr/pgmspace.h>

int dummy_putchar (char c) { return 0; }

#define fprintf_PSTR(fp, fmt, args...) ({   \
    static char pfmt[] PROGMEM = fmt;       \
    fprintf_P (fp, pfmt, ## args);          \
})

int
main (void)
{
    FILE *fp = fdevopen (dummy_putchar, NULL, 0);

    fprintf_PSTR (fp, "Hello World!\n");

    return 0;
}
-- end example --

And avr-objdump shows that the string went to .text:

Contents of section .data:
 800100 20001001 0000                         .....
Contents of section .text:
 0000 0c944d00 0c946a00 0c946a00 0c946a00  ..M...j...j...j.
 0010 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0020 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0030 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0040 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0050 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0060 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0070 0c946a00 0c946a00 0c946a00 0c946a00  ..j...j...j...j.
 0080 0c946a00 0c946a00 0c946a00 48656c6c  ..j...j...j.Hell
 0090 6f20576f 726c6421 0a001124 1fbecfef  o World!...$....
 00a0 d0e1debf cdbf11e0 a0e0b1e0 e4e5fae0  ................


I wonder if it would make sense to wrap all the *_P functions like
this. Then you wouldn't need to use PSTR at all.

Pros:

  - All *_P calls become cleaner. E.g, printf_P(PSTR("foo")); becomes
    printf_P("foo");

  - Works in C and C++.

Cons:

  - Is gcc smart enough to catch multiple copies of a string? A little
    experiment just now shows it's not.

  - Makes it impossible to pass a ptr to a fmt string.

Ted Roth



reply via email to

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