Zuerst stellte ich fest, dass es nicht möglich ist, den Typ der Konstante mit #define zu definieren. Warum ist das so?
Warum ist was? Es ist nicht wahr:
#define MY_INT_CONSTANT ((int) 12345)
Zweitens gibt es irgendwelche Vorteile, einen von ihnen gegenüber dem anderen zu verwenden?
Ja. #definedefiniert ein Makro, das bereits vor Beginn der Kompilierung ersetzt wird. constÄndert lediglich eine Variable so, dass der Compiler einen Fehler anzeigt, wenn Sie versuchen, ihn zu ändern. Es gibt Kontexte, in denen Sie a verwenden können, #defineaber Sie können a nicht verwenden const(obwohl ich Schwierigkeiten habe, einen mit dem neuesten Clang zu finden). Theoretisch constnimmt a Platz in der ausführbaren Datei ein und erfordert einen Verweis auf den Speicher. In der Praxis ist dies jedoch unbedeutend und kann vom Compiler optimiert werden.
consts sind viel compiler- und debuggerfreundlicher als #define s. In den meisten Fällen ist dies der übergeordnete Punkt, den Sie berücksichtigen sollten, wenn Sie eine Entscheidung treffen, welchen Sie verwenden möchten.
Ich dachte nur an einen Kontext, den Sie verwenden können, #defineaber nicht const. Wenn Sie eine Konstante haben, die Sie in vielen .cDateien verwenden möchten, #definestecken Sie sie einfach in einen Header. Mit a müssen constSie eine Definition in einer C-Datei haben und
// in a C file
const int MY_INT_CONST = 12345;
// in a header
extern const int MY_INT_CONST;
in einem Header. MY_INT_CONSTkann nicht als Größe eines statischen oder globalen Bereichsarrays in einer C-Datei verwendet werden, außer der, in der es definiert ist.
Für ganzzahlige Konstanten können Sie jedoch eine verwenden enum. Genau das macht Apple fast immer. Dies hat alle Vorteile von #defines und consts, funktioniert jedoch nur für ganzzahlige Konstanten.
// In a header
enum
{
MY_INT_CONST = 12345,
};
Welcher Weg ist schließlich effizienter und / oder sicherer?
#defineist theoretisch effizienter, obwohl moderne Compiler, wie gesagt, wahrscheinlich sicherstellen, dass es kaum Unterschiede gibt. #defineist insofern sicherer, als es immer ein Compilerfehler ist, zu versuchen, ihm zuzuweisen
#define FOO 5
// ....
FOO = 6; // Always a syntax error
consts kann dazu verleitet werden, zugewiesen zu werden, obwohl der Compiler möglicherweise Warnungen ausgibt:
const int FOO = 5;
// ...
(int) FOO = 6; // Can make this compile
Abhängig von der Plattform kann die Zuweisung zur Laufzeit immer noch fehlschlagen, wenn die Konstante in einem schreibgeschützten Segment platziert wird und das Verhalten gemäß dem C-Standard offiziell undefiniert ist.
Persönlich verwende ich für ganzzahlige Konstanten immer enums für Konstanten anderer Typen, es constsei denn, ich habe einen sehr guten Grund, dies nicht zu tun.