C++ Pendant zu #define

Gast #5064581
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.
Gast #5064591
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;
Gast #5064598
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.
Gast #5064604
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.
Gast #5064608
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.
Gast #5064613
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.
Gast #5064630
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.
Gast #5064786
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.
Gast #5065215
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.
Gast #5065219
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren