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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Georg (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

von Alex G. (dragongamer)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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


Bewertung
2 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
#define ROM_API     ((ROM_API_T *) ROM_API_BASE_LOC)

von Niklas G. (erlkoenig) Benutzerseite


Bewertung
1 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht lesenswert
... ein Zeiger.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.