Forum: Mikrocontroller und Digitale Elektronik C++ Pendant zu #define


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 schoof (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen, gibt es ein C++-Pendant zu der #define Direktive? Ich 
wollte letztens ein einfaches C-Programm in C++ umschreiben. Das Probem 
ist, dass #define ohne Datentyp arbeitet. In C++ würde ich das Konstrukt 
"const datatype name"  verwenden, aber wie mache ich das z.B. mit 
folgender Zeile:
1
#define LED_PORT PORTB

In C++ könnte das so aussehen:
1
const string LED_PORT = "PORTB";
 Aber C kennt doch gar keine Strings.

von Peter II (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
schoof schrieb:
> C++-Pendant zu der #define Direktive?
1
#define

die Bedeutung von define hat sich doch nicht bei C++ geändert, warum 
nicht einfach define stehen lassen, es hat unter C++ genauso seine 
Berechtigung.

von Dr. Sommer (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Peter II schrieb:
> es hat unter C++ genauso seine
> Berechtigung.
Ja, aber nicht die. Wie schoof schon erkannt hat hat #define keinen 
Typ und ist daher fehleranfällig (insbesondere bei C++ aufgrund 
typsensitiver Kontexte). Hinzu kommt die Tatsache dass #define keinen 
Scope kennt.

Die Antwort ist, dass du den Typ von PORTB heraussuchen und angeben 
musst. Ich vermute mal dass es einfach ein uint8_t ist:
1
volatile uint8_t& LED_PORT = PORTB;
Alternativ kannst du auch den Compiler das herausfinden lassen:
1
auto& LED_PORT = PORTB;

von Peter II (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Ja, aber nicht die. Wie schoof schon erkannt hat hat #define keinen
> Typ und ist daher fehleranfällig (insbesondere bei C++ aufgrund
> typsensitiver Kontexte).

das define wird ja nur ersetzt, die Typprüfung kommt dann an der Stelle 
wo das define verwendet wird. Und Dort wird dann auch der Typ richtig 
geprüft.
1
#define LED_PORT xxx

führt genauso zu einem Fehler.

von Dr. Sommer (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Peter II schrieb:
> führt genauso zu einem Fehler.
Nein. Im Kontext von Overloads oder templates kann ohne Meldung das 
falsche Overload/Template-Specialization ausgeführt werden. Und das 
Scoping-Problem besteht immer noch.

Naja, keine Lust das jetzt zu diskutieren, das ist ja alles ein alter 
Hut, der schon dutzend Mal wieder gekäut wurde. Kann man alles online 
nachlesen oder zB in den C++ Büchern von Bjarne Stroustrup.

Das Ergebnis ist, auch wenn die Vorteile von richtigen Konstanten keine 
Totschlagargumente bieten, sind es dennoch Vorteile, während es in 
solchen Fällen absolut keinen Grund gibt, #define zu nutzen (außer dem 
hübschen #-Zeichen). Daher sollte bei so etwas (fast) immer eine 
Konstante angewendet werden.

von Peter II (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Das Ergebnis ist, auch wenn die Vorteile von richtigen Konstanten keine
> Totschlagargumente bieten, sind es dennoch Vorteile, während es in
> solchen Fällen absolut keinen Grund gibt, #define zu nutzen (außer dem
> hübschen #-Zeichen). Daher sollte bei so etwas (fast) immer eine
> Konstante angewendet werden.

da wir nicht wissen was noch alles mit dem #define gemacht wird, kann 
man es nicht 1:1 ersetzen.
1
#ifndef LED_PORT
2
   ....

geht dann einfach nicht mehr.

von ui (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Das Ergebnis ist, auch wenn die Vorteile von richtigen Konstanten keine
> Totschlagargumente bieten, sind es dennoch Vorteile, während es in
> solchen Fällen absolut keinen Grund gibt, #define zu nutzen (außer dem
> hübschen #-Zeichen). Daher sollte bei so etwas (fast) immer eine
> Konstante angewendet werden.

Es gibt auch in C keine Argumente Konstanten mit #defines zu 
deklarieren.
Da werden gerne viele verschiedene Dinge gemischt.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
ui schrieb:
> Es gibt auch in C keine Argumente Konstanten mit #defines zu
> deklarieren.
Doch, das geht in C nicht:
1
const size_t N = 42;
2
int array [N];
Weil "const" keine Konstanten definiert, sondern lediglich eine 
read-only Variable. In C++ geht das aber.

Peter II schrieb:
> #ifndef LED_PORT
>    ....
>
> geht dann einfach nicht mehr.
Das stimmt; man kann solche fiesen #ifdef Konstrukte aber oft durch 
templates ersetzen.

von Sven B. (scummos)


Bewertung
-1 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
>
1
volatile uint8_t& LED_PORT = PORTB;
> Alternativ kannst du auch den Compiler das herausfinden lassen:
>
1
auto& LED_PORT = PORTB;

volatile ist ein type qualifier und du kannst ihn nicht weglassen weil 
du auto schreibst. Die Alternative mit auto zu
volatile uint8_t& x = y;
ist
volatile auto& x = y;

von schoof (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sven B. schrieb:
> volatile uint8_t& x = y;

Ok das ist doch was, danke euch für die Diskussion.

von Dr. Sommer (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Sven B. schrieb:
> volatile ist ein type qualifier und du kannst ihn nicht weglassen weil
> du auto schreibst.
Also ich kann das:
1
#include <iomanip>
2
#include <iostream>
3
#include <type_traits>
4
5
volatile int X;
6
auto& x = X;
7
8
int main () {
9
  std::cout << std::boolalpha << std::is_reference<decltype(x)>::value << std::endl;
10
  std::cout << std::boolalpha << std::is_volatile<std::remove_reference<decltype(x)>::type>::value << std::endl;
11
}
gibt bei mir 2x true aus. Es sollte auch einen Fehler geben wenn man 
eine nicht-volatile Referenz auf eine volatile Variable anlegt.

von Sven B. (scummos)


Bewertung
0 lesenswert
nicht lesenswert
Hm ok, interessant.

von n.b. (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> Ja, aber nicht die. Wie schoof schon erkannt hat hat #define keinen
> Typ und ist daher fehleranfällig (insbesondere bei C++ aufgrund
> typsensitiver Kontexte). Hinzu kommt die Tatsache dass #define keinen
> Scope kennt.

#define hat mit dem Compiler überhaupt nichts zu tun. Das erledigt alles 
der Präprozessor und der kennt wiederum nur Text und hat keine Ahnung 
von der Programmiersprache und den Strukturen.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Korrekt. Genau das ist das Problem. Der Präprozessor zerpflückt das 
Programm ohne Links und rechts zu gucken.

Na ja, das Thema ist schon längst genug diskutiert. Ich verstehe nicht 
warum hier ständig Leute dagegen diskutieren.

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.