Forum: Compiler & IDEs C: __attribute__ als cast in Parameter


von Luigi Ganove (Gast)


Lesenswert?

Hallo,

ich habe eine Funktion, welche deklariert ist als
1
int bla(char *str, const char *format, ...)

Einer der unzähligen Aufrufe ist z.B. folgendermaßen:
1
static const char TEST[] __attribute__((section(".irom.text"))) = "DIES IST EIN TEST";
2
len = bla(buff, TEST);

Dieses Gebilde soll jetzt aber ein einziger Aufruf werden, d.h. die 
Deklaration der Konstante soll mit in den Aufruf hinein. Wie mache ich 
das? Es ist wichtig, dass das section-Attribut zum Tragen kommt, damit 
mir die Ganzen konstanten Texte am Ende nicht im RAM liegen.

von Peter II (Gast)


Lesenswert?

Luigi Ganove schrieb:
> Dieses Gebilde soll jetzt aber ein einziger Aufruf werden, d.h. die
> Deklaration der Konstante soll mit in den Aufruf hinein.

geht nicht. Warum muss das in einer Zeile stehen?

von Luigi Ganove (Gast)


Lesenswert?

Hmmmm. Das ist schlecht.
Es soll den Quelltext übersichtlicher machen.

Geht es vielleicht als Makro? Ich habe da schon ewig rumprobiert, aber 
der Rückgabewert (also "len") macht mir immer einen Strich durch die 
Rechnung.

von Markus F. (mfro)


Lesenswert?

Mir fällt auf, dass solche Fragen ("wie kann ich das 
übersichtlicher...") in letzter Zeit öfter auftauchen.

M.E. gibt's dafür nur eine Antwort: übersichtlich ist das, was genauso 
aussieht wie das, was es ist.

Auch wenn's schon viele versucht haben: man kann aus C kein Pascal, 
Algol oder was auch immer machen; es bleibt doch immer C.

In deinem Beispiel hast Du 1.) eine Variablendeklaration, die ein 
Attribut verpasst bekommt + die Zuweisung eines Werts.

Und Du hast 2.) einen Funktionsaufruf mit einer Zuweisung.

Was gewinnst Du dadurch, dass Du 1.) und 2.) (die ausser "TEST" nichts 
miteinander zu tun haben) miteinander verwurschtelst?

Ich wette, selbst wenn Du's hinkriegst, wirst Du's in ein oder zwei 
Monaten selbst nicht mehr verstehen.

Übersichtlich ist ein Programm m.E. dann, wenn Einer, der den Code noch 
nie gesehen hat, innerhalb von ein paar Minuten versteht, worum's geht.

Mit kryptischen Makros erreichst Du das nicht.

von ich (Gast)


Lesenswert?

Mit gcc extension geht das recht angenehm, das Makro ist aber kein 
Standard-C.
1
#define BLA(str, format, ...) ({ \
2
  static const char rom_format[] __attribute__((section(".irom.text"))) = format; \
3
  bla(str, rom_format); \
4
})
5
6
len = BLA(buff, "DIES IST EIN TEST");

von ich (Gast)


Lesenswert?

Sorry, hab das ... vergessen, da muss noch ein _VA_ARGS_ rein:
1
bla(str, rom_format, ##__VA_ARGS__); \

von Luigi Ganove (Gast)


Lesenswert?

Ich will letztlich eine (s)printf-Funktion erhalten, die ich genau so 
aufrufen kann, wie die Standard-Funktion, nur, dass sie eben die 
bestehenden Strings in den Flash verfrachtet. Ich gewinne quasi 
Kompatibilität bzw. Portabilität.

von Stefan E. (sternst)


Lesenswert?

Oder wenn GCC, dann alternativ zum Vorschlag von "ich":
1
#define IROMSTR(str) \
2
(__extension__({static const char s[] __attribute__((section(".irom.text"))) = (str); &s[0];}))
3
4
len = bla(buff,IROMSTR("DIES IST EIN TEST"));

von Luigi Ganove (Gast)


Lesenswert?

Danke. Ist es normal, dass die Variable "s" im Post über mir dann mit 
meiner lokalen Variable "s" im Code kollidiert? Ich habe Stunden nach 
einem Fehler gesucht, bis ich "s" in dem Makro mal umbenannt habe...
Ich dachte eigentlich, die geschweiften Klammern ermöglichen das 
Erzeugen einer neuen lokalen Variablen.

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.