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


von schoof (Gast)


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)


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)


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)


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)


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)


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)


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)


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)


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)


Lesenswert?

Sven B. schrieb:
> volatile uint8_t& x = y;

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

von Dr. Sommer (Gast)


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)


Lesenswert?

Hm ok, interessant.

von n.b. (Gast)


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)


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.

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.