Forum: Compiler & IDEs Wie initialisiert man sowas korrekt?


von Mensch Müller (Gast)


Lesenswert?

Ich habe zwei Zeichenketten im Flash, die zufällig identisch sind. Lässt 
sich nicht vermeiden (hat mit verschiedenen Sprachen zu tun). Ich habe 
das Ganze mal zu einem Minimalbeispiel zusammengedampft, das nur das 
Wesentliche enthält:
1
#include <inttypes.h>
2
#include <avr/io.h>
3
4
const __flash char TEST1[] = "test";
5
const __flash char TEST2[] = "test";
6
7
static void use(const __flash char *data) {
8
  char c;
9
  while ((c = *data++) != '\0') GPIOR1 = c;
10
}
11
12
int __attribute__((OS_main)) main(void) {
13
  use(TEST1);
14
  use(TEST2);
15
  while (1);
16
}

Kompiliert wird das Ganze mit avr-gcc 5.2.1 mit u.a. dem Parameter 
-fmerge-all-constants, der in solchen Fällen Platz spart. Nun ist es so, 
dass folgende Warnung erscheint:
1
test.c: In function 'main':
2
test.c:5:20: warning: uninitialized variable 'TEST2' put into program memory area [-Wuninitialized]
3
 const __flash char TEST2[] = "test";

Warum passiert das? Und wie kann ich die Warnung verhindern (ich kann 
nicht auf -Wuninitialized oder -fmerge-all-constants verzichten)?

von Markus F. (mfro)


Lesenswert?

Mensch Müller schrieb:
> Warum passiert das?

anscheinend merkt der Compiler nicht, daß er eins von den beiden 
Symbolen schon aufs andere gelegt hat.

Ich würde zunächst mal den Weg des geringsten Widerstandes gehen und 
versuchen, eine der beiden Variablen als const volatile zu deklarieren.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Könnte es sein, dass -fmerge-all-constants zur Link-Zeit wirkt, und zur 
Compile-Zeit dann TEST2 unintialisiert "aussieht"? Das wäre dann evtl. 
ein Bug. Dein Minimalbeispiel würde ich mal bei 
https://gcc.gnu.org/bugzilla/ melden.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Di P. schrieb:
> Dein Minimalbeispiel würde ich mal bei
> https://gcc.gnu.org/bugzilla/ melden.

Bitte nicht, da gibt's bereis einen PR für.

von Mark B. (markbrandis)


Lesenswert?

Johann L. schrieb:
> Di P. schrieb:
>> Dein Minimalbeispiel würde ich mal bei
>> https://gcc.gnu.org/bugzilla/ melden.
>
> Bitte nicht, da gibt's bereis einen PR für.

Kannst Du bitte die ID nennen? Ich hab grad versucht den per 
Volltextsuche zu finden, ist aber nicht so einfach.

von Mensch Müller (Gast)


Lesenswert?

Also schonwieder ein Bug. :/ Oh boy...

von Mensch Müller (Gast)


Lesenswert?

https://de.m.wikipedia.org/wiki/Programmfehler

GCC arbeitet hier offenkundig nicht korrekt. Die Variable ist im 
Quelltext eindeutig initialisiert.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Es gab mal PR57597.  Aber in deinem Code dürfen TEST1 und TEST2 eh nicht 
gemergt werden.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Weshalb nicht? (Bitte lass dir nicht alles aus der Nase ziehen...)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Die Warnung kann ich nicht nachvollziehen, ich geb's auf die Optionen zu 
raten...

von Mark B. (markbrandis)


Lesenswert?

Johann L. schrieb:
> Aber in deinem Code dürfen TEST1 und TEST2 eh nicht gemergt werden.

Ist das deswegen?

1
-fmerge-constants
2
    Attempt to merge identical constants (string constants 
3
    and floating-point constants) across compilation units.

Mit "across compilation units" ist in dem Beispiel oben ja nüscht.

: Bearbeitet durch User
von Mensch Müller (Gast)


Lesenswert?

Warum Optionen raten? Könnt ihr es nicht mit dem Code nachvollziehen? 
Dann muss ich später nochmal gucken, ob ich eine spezielle weitere 
Option verwende.

von Mensch Müller (Gast)


Lesenswert?

Da ist eigentlich keine Zauberei dabei. Das reicht für den Fehler:

-mmcu=atmega168 -Os -Wall -fmerge-all-constants

von Mensch Müller (Gast)


Lesenswert?

Übrigens ist es sehr positiv, dass die Konstanten "gemergt" werden und 
so Flash frei wird. Ohne diese Option würden wir unsere Software nämlich 
nicht in den Chip reinkriegen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Okay, damit kann ich's nachvollziehen.  Wenn du nen PR anlegst dann 
bitte ohne Header, z.B.
1
const __flash char test1[] = "test";
2
const __flash char test2[] = "test";
3
4
char func (unsigned char c)
5
{
6
  return test1[c] + test2[c];
7
}
Die Warnung wird warscheinlich zu spät ausgegeben; sie zu früh 
auszugeben bringt hingegen PR34734 :-)  Bislang wurde das Problem 
wahrscheinlich durch PR57597 maskiert.

Bis das behoben ist kannst du ja -Wuninitialized deaktivieren oder 
rausfiltern falls "progmem memory area" drin vorkommt (ohne NLS, das man 
eh deaktivieren sollte).

Allerdings wüsste ich nicht, dass momentan jemand Zeit in avr-gcc 
investiert.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

Johann L. schrieb:
> Allerdings wüsste ich nicht, dass momentan jemand Zeit in avr-gcc
> investiert.

Heißt das, dass man künftig auf deine Beiträge verzichten muss?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.