Forum: Compiler & IDEs bild.h in mehreren Dateien - Optimierungsfrage


von Michael (Gast)


Lesenswert?

Hallo,

habe mit einem bin2hex-Tool erstellte *.h-Dateien mit folgendem Aufbau
1
#include <inttypes.h>
2
#include <avr/pgmspace.h>
3
static uint8_t __attribute__ ((progmem))  Bild[]= {
4
0x50,0x34,0x0A, //.. noch etliche Bytes
5
};

Wenn ich diese *.h-Daten per #include "Bild.h" in mehrere *.c-Module
einfüge, wird die bild.h Flashverschwendend mit jedem include
zusätzlich in die Ausgabe-*.hex-Datei eingebaut.

Wie kann ich das verhindern / anders lösen?

Danke für nen Tip!

von Sssssss (Gast)


Lesenswert?

so wie man das auch mit anderen h files verhindert:
1
#ifndef _BILD_H_
2
#define _BILD_H_
3
4
#include <inttypes.h> 
5
#include <avr/pgmspace.h> 
6
static uint8_t _<u>_attribute_</u>_ ((progmem))  Bild[]= { 
7
0x50,0x34,0x0A, //.. noch etliche Bytes 
8
}; 
9
#endif

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Welchen Sinn hat es, eine Variable mit dem Storage Class Specifier
"static" in einer Headerdatei zu deklarieren?

Wenn nur ein Sourcemodul auf die Variable Bild zugreifen muss, dann
sollte die Variable auch nur innerhalb dieses Sourcemoduls deklariert
werden.

Wenn aber mehrere Sourcemodule auf die Variable zugreifen sollen, dann
muss das "static" verschwinden und durch ein "extern" ersetzt
werden. Die Initialisierung der Variablen gehört dann in ein
Sourcemodul.

Also:

bild.h
   extern uint8_t attribute ((progmem)) Bild[];

bild.c
   uint8_t attribute ((progmem)) Bild[] = { ,,, };

von Michael (Gast)


Lesenswert?

Dankeschön!
Konkretes Problem gelöst.

Ohne jetzt einen extra Thread aufzumachen ne Verständnisfrage:

wenn ich folgendes habe:

/*modul1.c*/
int m1;
extern int m2;

/*modul2.c*/
int m2;
extern int m1;

Ergibt sich daraus kein Henne-Ei-Problem? Die Module werden doch
nacheinander compiliert. Beim compilieren von modul1 steht die Adresse
von extern int m2 ja noch gar nicht fest. Wie wird dann modul1.o
erzeugt?

von Rolf Magnus (Gast)


Lesenswert?

> Beim compilieren von modul1 steht die Adresse
> von extern int m2 ja noch gar nicht fest

Braucht sie ja auch nicht. Das ist nicht Sache des Compilers, sondern
des Linkers.

> Wie wird dann modul1.o erzeugt?

Jede der Dateien wird für sich compiliert. Der Compiler weiß jeweils
nichts vom Inhalt der anderen. Daher ist die Reihenfolge, in der
compiliert wird, auch egal.

von OldBug (Gast)


Lesenswert?

>so wie man das auch mit anderen h files verhindert:
>
>#ifndef _BILD_H_
>#define _BILD_H_

Bitte nicht, das könnte mit der C-Lib oder irgendwelchen anderen
internas der Toolchain kollidieren. Lieber so:
1
#ifndef BILD_H
2
#define BILD_H
3
...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Ansatz von Ssss hilft beim hier geschilderten Problem übrigens
nicht; jedes Modul bindet bild.h exakt einmal ein.
Und nu?

Diese #ifndef/#define/#endif-Geschichte hilft nur davor, eine
Headerdatei mehrfach in einem Sourcemodul einzubinden.
Was mit etwas Struktur und Selbstdisziplin ein eh' nicht auftretendes
Problem sein dürfte.

von Sssssss (Gast)


Lesenswert?

Oh sorry hab nicht richtig gelesen.
hatte nicht gesehen dass du die var in der h datei mit daten füllst.
Mach dort lieber wie oben gesagt nen
extern uint8_t  ((progmem))  Bild[];
draus und dann in bild.c
das ganze zuweisen ;) (ohne extern dort)

von Michael (Gast)


Lesenswert?

Danke für's auf die Sprünge helfen! :-)

Michael

von Rolf Magnus (Gast)


Lesenswert?

> Was mit etwas Struktur und Selbstdisziplin ein eh' nicht
> auftretendes Problem sein dürfte.

Doch, das tritt auch dann auf. Wenn man mit Headern arbeitet, die
"self contained" sind (und das sollte man), lässt es sich oft gar
nicht vermeiden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Magst Du das bitte elaborieren?

a) Was präzise sind für Dich "self contained" Headerdateien?
und
b) warum sollte man die Deiner Ansicht nach verwenden?

von Rolf Magnus (Gast)


Lesenswert?

> a) Was präzise sind für Dich "self contained" Headerdateien?

Wenn ich ein #include <meinheader.h> ohne ein anderes vorheriges
#include mache, sollten keine Fehlermeldungen auftreten, die dadurch
kommen, daß der Header einen anderen Header benötigt. Er sollte ein
dazu evtl. nötiges #include selbst enthalten.
Wenn ich jetzt z.B. die Header a.h und b.h habe, die beide den Header
c.h benötigen, dann wird c.h automatisch doppelt enthalten sein, wenn
ich irgendwo ein

#include "a.h"
#include "b.h"

stehen habe. Da die Vermeidung der Mehrfacheinbindung über
Iclude-Guards aber trivial ist, ist das ja kein Problem. Gute Editoren
fügen die Include-Guards eh entweder automatisch oder per Knopfdruck
ein.

> b) warum sollte man die Deiner Ansicht nach verwenden?

Weil es verlorene Zeit ist, jeden Header zu durchsuchen, um
rauszubekommen, welche anderen Header der noch vorher benötigen könnte,
und weil es auch unnötiger Mehraufwand ist, sich drum kümmern zu müssen,
daß alle Header in genau der richtigen Reihenfolge eingebunden werden.

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.