[AVR] compiler optimiert strings nicht richtig

OP #1348155
Lesenswert?

Hi,
Ich hab ein Problem/Frage:

Ich hab  in meinem Code mehrere Stellen, wo ich Meldungen ausgebe.
es gibt merhere Meldungen, die den selben Text enthalten.

Die strings sind komplett identisch (selbes #define), jedoch legt der 
compiler die 2 mal an, anstatt sie einmal anzulegen und den pointer auf 
das selbe zeigen zu lassen.

Die zeichenketten selbst liegen im program memory, können also nicht 
verändert werden.

beispiel:
1
/**
2
 @brief macros for automatically storing string constant in program memory
3
*/
4
#define lcd_puts_P(__s)         lcd_puts_p(PSTR(__s))
5

6
#define ERROR_SD_READ "Error SD_read"
7

8

9

10

11

12
  if( 0 != getSDinfos(&sdInfo) ){
13
    lcd_init(LCD_DISP_ON);
14
    lcd_puts_P( ERROR_SD_READ );
15
    HALT;
16
  }
17

18

19
  if(0 != SD_readSingleBlock(sdInfo.rootDirSector, (uint8*)s_logBuf,8)) /* temporary use logging buffer */
20
  {
21
    lcd_init(LCD_DISP_ON);
22
    lcd_puts_P( ERROR_SD_READ );
23
    HALT;
24
  }

wenn ich jetzt ins list-file oder ins elf-file schaue, gibts den string 
"Error SD_read" mehrmals.

Was muss ich tun, damit der string nur einmal eingebunden wird?
OP #1348207
Lesenswert?

>Ein 'guter' Compiler macht das von alleine. Zur Not auf 'size'
>optimieren lassen.

hätt ich ja auch gedacht

ist halt ein gcc
duck und weg

und auf size optimieren ist schon an.

aber holgers variante scheint zu funktionieren.

Trotzdem hätt ich lieber ne Variante, wo das der compiler automatisch 
macht.
#1348208
Lesenswert?

Worin liegt das Problem, den String nur einmal zu definieren, ihn aber 
mehrmals zu verwenden?
1
char ERROR_SD_READ[] PROGMEM = "Error SD_read";
2
...
3
lcd_puts_P( ERROR_SD_READ );

Und ja, der String ist dann nur einmal im Speicher (Flash).
Und nein, das verbraucht keinen zusätzlichen Platz für irgendwelche 
Pointer.
#1348858
Lesenswert?

Johann L. schrieb:
> Jeder String ist ein eigenständiges Objekt. Ich wüsst nicht wie gcc das
> optimieren können sollte.

Es geht um Stringliterale gleichen Inhalts. Hier wird normalerweise der 
eigentliche String nur einmal angelegt. Das Section-Attribut hebelt das 
aber irgendwie aus, und der String wird mehrfach angelegt.
Persönliche Seite #1349035
Lesenswert?

Stefan Ernst schrieb:
> Was willst du mir damit sagen? Natürlich sind STR1 und STR2 zwei
> unterschiedliche Objekte. Es geht nicht um Variablen, sondern die
> Literale.
>
>
1
> Func1("Hallo");
2
> Func2("Hallo");
3
>
> An beide Funktionen wird der selbe Pointer übergeben.

Du hast aber keine Literale:
1
#include <avr/pgmspace.h>
2

3
extern void foo1 (const char*);
4
extern void foo2 (const char*);
5

6
void foo (void)
7
{
8
    foo1 (PSTR ("hallo"));
9
    foo2 (PSTR ("hallo"));
10
}

Wird expandiert zu
1
void foo (void)
2
{
3
    foo1 ((__extension__({static char __c[] __attribute__((__progmem__)) = ("hallo"); &__c[0];})));
4
    foo2 ((__extension__({static char __c[] __attribute__((__progmem__)) = ("hallo"); &__c[0];})));
5
}

und damit gibt es zwei __c-Objekte, eines für jedes "hallo".

Johann

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren