Forum: Mikrocontroller und Digitale Elektronik Was macht dieses define in C?


von Georg (Gast)


Lesenswert?

Hallo,

in einer library von NXP habe ich folgendes Define gefunden:
1
#define ROM_API_BASE_LOC    0x03000200UL
2
#define ROM_API     (*(ROM_API_T * *) ROM_API_BASE_LOC)

Ich verstehe nicht so ganz, was das macht. die zwei "* *" verwirren mich 
dabei. Ist das ein doppelter Pointer?
Kann mir jemand ein bisschen erklären, wohin ROM_API nun zeigt?

Vielen Dank!

von Karl M. (Gast)


Lesenswert?

Hallo,
hast Du dir mal die Definition angesehen?
1
typedef struct ROM_API {
2
  162  const uint32_t    unused[2];
3
  163  const CCAN_API_T  *pCCAND; 
4
  164 } ROM_API_T;

Quellen:
[1] http://67.222.144.123/lpcopen/v1.03/struct_r_o_m___a_p_i___t.html
[2] http://67.222.144.123/lpcopen/v1.03/ccand__11xx_8h_source.html

Dann ist die innere Klammer ein Cast auf (ROM_API_T  ), diese wird 
durch das *(...) wird die Adresse ROM_API_BASE_LOC von Datentype Pointer 
auf ROM_API_T.

von Jens (Gast)


Lesenswert?

ROM_API_BASE_LOC wird als Zeiger interpretiert und mit * vor den 
Klammern auf den dort hinterlegten Wert zugegriffen. Diesen Wert gibt 
ROM_API aus.

(ROM_API_T  ) ist ein Zeiger auf einen Zeiger. Was ROM_API_T kann ich 
dir nicht sagen.

von Markus F. (mfro)


Lesenswert?

Georg schrieb:
> #define ROM_API_BASE_LOC    0x03000200UL
> #define ROM_API     (*(ROM_API_T  ) ROM_API_BASE_LOC)

ROM_API_BASE_LOC ist ein unsigned long Literal, das hiermit
1
(ROM_API_T * *) ROM_API_BASE_LOC
als Zeiger auf einen Zeiger auf ein Objekt vom Typ ROM_API_T 
(wahrscheinlich ein struct?) gecasted wird.

Damit
1
(*(ROM_API_T * *) ROM_API_BASE_LOC)
 wird dieser Zeiger dereferenziert - d.h. ROM_API ist nun ein Zeiger auf 
ein ROM_API_T.

Damit kannst Du mit den Elementen von ROM_API direkt über den -> 
Operator hantieren.

von Hmm (Gast)


Lesenswert?

Ahh...ich liebe C++ ...ein wenig das Gehirn quälen  :-)

von Alex G. (dragongamer)


Lesenswert?

Hmm schrieb:
> Ahh...ich liebe C++ ...ein wenig das Gehirn quälen  :-)
Wie wahr (und das sagt einer der seine Bachelor Thesis mit C++ Projekt 
geschrieben hat)...
Andererseits gabs Gelegenheiten wo Makros auch in Java ganz nützlich 
wären, nur man sollte es nicht wie hier übertreiben.

von foobar (Gast)


Lesenswert?

>> Ahh...ich liebe C++ ...ein wenig das Gehirn quälen  :-)
> Wie wahr (und das sagt einer der seine Bachelor Thesis mit C++ Projekt
> geschrieben hat)...

Wer vor Pointern Angst hat, sollte um Low-Level-Programmierung und C/C++ 
nen ganz großen Bogen machen!

> [...] nur man sollte es nicht wie hier übertreiben.

Ernsthaft? Einfacher geht es doch gar nicht. Wie würdest du denn den 
Zugriff auf eine Struktur machen, dessen Adresse in 0x3000200 steht?

von Georg (Gast)


Lesenswert?

Danke an alle für die Denkanstöße und dass ihr mir auf die Sprünge 
geholfen habt!
Jetzt ist es klar geworden ;-)

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Hmm schrieb:
> Ahh...ich liebe C++ ...ein wenig das Gehirn quälen  :-)

Nur ist das eher C-Stil... In C++ kann man das sauberer so machen:
1
static constexpr std::uintptr_t ROM_API_BASE_LOC = 0x03000200UL;
2
static ROM_API_T* const ROM_API = *reinterpret_cast<ROM_API_T**> (ROM_API_BASE_LOC);

Alex G. schrieb:
> Andererseits gabs Gelegenheiten wo Makros auch in Java ganz nützlich
> wären, nur man sollte es nicht wie hier übertreiben.
Da Makros ja nur simple Textersetzung sind und man damit viel falsch 
machen kann, haben Java (und die meisten anderen Sprachen) das nicht, 
dafür aber andere Mechanismen zur Abstraktion.

foobar schrieb:
> Ernsthaft? Einfacher geht es doch gar nicht. Wie würdest du denn den
> Zugriff auf eine Struktur machen, dessen Adresse in 0x3000200 steht?
Eine Alternative wäre:
1
#ifdef __cplusplus
2
extern "C"
3
#else
4
extern
5
#endif
6
ROM_API_T* const ROM_API;
und im Linker-Script (hier: GNU LD Syntax):
1
ROM_API = 0x03000200;

von daudidadaus (Gast)


Lesenswert?

#define ROM_API     ((ROM_API_T *) ROM_API_BASE_LOC)

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

daudidadaus schrieb:
> #define ROM_API     ((ROM_API_T *) ROM_API_BASE_LOC)

Da fehlt aber eine Dereferenzierung. An der Adresse 0x03000200UL im 
Speicher steht wieder nur eine Adresse...

von daudidadaus (Gast)


Lesenswert?

... ein Zeiger.

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.