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. #define
definiert 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, #define
aber Sie können a nicht verwenden const
(obwohl ich Schwierigkeiten habe, einen mit dem neuesten Clang zu finden). Theoretisch const
nimmt 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.
const
s 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, #define
aber nicht const
. Wenn Sie eine Konstante haben, die Sie in vielen .c
Dateien verwenden möchten, #define
stecken Sie sie einfach in einen Header. Mit a müssen const
Sie 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_CONST
kann 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 #define
s und const
s, funktioniert jedoch nur für ganzzahlige Konstanten.
// In a header
enum
{
MY_INT_CONST = 12345,
};
Welcher Weg ist schließlich effizienter und / oder sicherer?
#define
ist theoretisch effizienter, obwohl moderne Compiler, wie gesagt, wahrscheinlich sicherstellen, dass es kaum Unterschiede gibt. #define
ist insofern sicherer, als es immer ein Compilerfehler ist, zu versuchen, ihm zuzuweisen
#define FOO 5
// ....
FOO = 6; // Always a syntax error
const
s 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 enum
s für Konstanten anderer Typen, es const
sei denn, ich habe einen sehr guten Grund, dies nicht zu tun.