Cast von MAKRO nach int
-
knivil schrieb:
Noch ne Gegenfrage: Von welchem Typ sind 234, 1, 6 oder 13? Sind sie natuerliche Zahlen, ganze, gebrochene, reele oder gar komplexe? Sie sind alles! Deswegen ist die Frage nach dem Typ von Zahlen eine schlecht gestellte Frage. Variablen haben Typen, Zahlen im allgemeinen nicht.
Falsch, falsch, falsch!
void function(int value); void function(short value); void function(unsigned int value); ... int main() { function(25); }Na, welche Funktion wird hier wohl aufgerufen?

Antwort: Die mit int.
Weil eine Zahl, die keinem Typ zugewiesen ist, per default ein int ist und nicht "alles".
Booyashaka!
-
I know it better schrieb:
[...]Weil eine Zahl, die keinem Typ zugewiesen ist, per default ein int ist und nicht "alles".[...]
Das stimmt auch nicht.
Was wird z.B. hierbei aufgerufen:function(42.0);
Dabei hat die Zahl auch keinen Typen "zugewiesen", und trotzdem ist es kein int.Edit: komische Schreibfehler und eigene Blödheit
-
Tachyon schrieb:
Das hat die Zahl auch keinen Typen "zugewiesen", und trotzdem ist es kein int.
Ich bin mir gerade nicht sicher ob 42.0 double oder float, glaube aber ersteres ist.
-
Tachyon schrieb:
I know it better schrieb:
[...]Weil eine Zahl, die keinem Typ zugewiesen ist, per default ein int ist und nicht "alles".[...]
Das stimmt auch nicht.
[...]Weil eine literale Zahl, die ohne Angabe eines Dezimalpunkts notiert ist, ohne Typpostfix automatisch ein int ist.
(Der Passus "keinem Typ zugewiesen" ist so auch mißverständlich. Durch die Zuweisung an eine Variable vom Typ != int ändert sich nämlich der Typ des Literals nicht)
-
lord.hong schrieb:
Wo liegt dann genau der Unterschied zwischen diesen zwei Zeilen:
#define NUMBER 4711 const int NUMBER = 4711;Soll das wirkilich identisch sein?
Ein möglicher Unterschied ist folgendes (vorsicht, das Makro-Gefrickel wird nicht für zu Hause empfohlen ;))
#define NUMBER 4711 double foo4711(); double foo4712(); void bar() { int i = NUMBER; //okay, das ginge auch mit const int NUMBER... float f = 0.34##NUMBER##f; //0.344711f !! double d = foo##NUMBER##(); //Aufruf von foo4711() }Soll heißen: Makros sind wirklich nur reine Textersetzung die man sogar als Teilstrings von Variablennamen benutzen kann. Der Compiler sieht nichts davon, deshalb kannst du bei Makros auf Typsicherheit und sinnvolle Fehlermeldungen nicht zählen - einer der Hauptgründe weshalb sie soweit möglich gemieden werden.
-
LordJaxom schrieb:
Beim #define sieht der Compiler von NUMBER nichts mehr. Der Compiler sieht, überall wo vor dem Präprozessorlauf NUMBER stand, nun ein Integerliteral mit dem Wert 4711.
Beim const int sieht der Compiler ein Symbol NUMBER, welches er (wegen dem const) bei jedem Auftauchen durch seinen Wert 4711 ersetzen darf (aber IMO nicht muss). Ein Unterschied ist z.B., dass man hier mit &NUMBER eine Adresse nehmen kann.
Danke, dass war mein Problem. Der Compiler sieht nur noch 4711, was er als int interpretiert - was in meinem Beispiel auch richtig ist.
Mit einem Postfix f
#define NUMBER 4711fkönnte ich den Typ float erzwingen oder einen implizieten cast vornehmen
#define NUMBER 4711 void doSomething( float fNumber); doSomething( NUMBER ); doSomething( 4711 );Nun ist mir klar, wie der Compiler den Typ herausfindet.
-
pumuckl schrieb:
Soll heißen: Makros sind wirklich nur reine Textersetzung die man sogar als Teilstrings von Variablennamen benutzen kann. Der Compiler sieht nichts davon, deshalb kannst du bei Makros auf Typsicherheit und sinnvolle Fehlermeldungen nicht zählen - einer der Hauptgründe weshalb sie soweit möglich gemieden werden.
Stimmt, wenn ich in einem Software-Team arbeiten würde, welches auf Typsicherheit wert legen würde.

Die Realität sieht leider anders aus.

knivil schrieb:
Gegenfrage: Von welchem Typ ist 42 hier:
float ultimateAnswer = 42;Na? Es spielt keine Rolle, da der Compiler schlau ist und die Variable mit 42 als float belegt. Noch ne Gegenfrage: Von welchem Typ sind 234, 1, 6 oder 13? Sind sie natuerliche Zahlen, ganze, gebrochene, reele oder gar komplexe? Sie sind alles! Deswegen ist die Frage nach dem Typ von Zahlen eine schlecht gestellte Frage. Variablen haben Typen, Zahlen im allgemeinen nicht.
-
Viel bessere Fehler, warum man Makros nur mit grösster Vorsicht benutzen sollte:
enum Type { NUMBER, TEXT, IMAGE, FILE };Tjo, das gibt einen äusserst seltsamen Kompilerfehler. Dem Präprozessor sind Scopes scheiss egal.
Und auch einen weit bekannten blöder Fehler, ist der folgende:
#include <windows.h> #include <limits> int main() { std::numeric_limits<int>::max(); return 0; }maxist ein Makro inwindows.h, was zu einem Fehler führt in diesem Code.Übrigens, die integer und floating point Literale sind im Standard so definiert, dass der Compiler eine freie Wahl, mit den folgenden Regeln:
Sufix Decimal constant Octal or hexadecimal constant ------------------------------------------------------------------------------- none int int long int unsigned int long int unsigned long int ------------------------------------------------------------------------------- u or U unsigned int unsigned int unsigned long int unsigned long int ------------------------------------------------------------------------------- l or L long int long int unsigned long int ------------------------------------------------------------------------------- Both u or U unsigned long int unsigned long int and l or L ------------------------------------------------------------------------------- Floating Point: 1. .0 1e1 1.e2 1.0e3 sind alles doubles. Für float braucht es das Suffix f oder F: 1.f .0f 1e1f 1.e2f 1.0e3f Für long double braucht es das Suffix l oder L: 1.l .0l 1e1l 1.e2l 1.0e3lIch hoffe ich habe jetzt nichts falsch abgeschrieben

Grüssli
-
Naja, freie Wahl nun auch nicht. Die Regel ist IIRC mehr "nimm das erste aus der Liste, wo die Zahl reinpasst."
-
lord.hong schrieb:
Stimmt, wenn ich in einem Software-Team arbeiten würde, welches auf Typsicherheit wert legen würde.

Die Realität sieht leider anders aus.

Was nicht bedeuten muss dass du es ihnen nachmachen und auf Typsicherheit verzichten musst.