По-перше, я виявив, що неможливо визначити тип константи за допомогою #define, чому це?
Чому це що? Це неправда:
#define MY_INT_CONSTANT ((int) 12345)
По-друге, чи є якісь переваги використання одного з них перед іншим?
Так. #defineвизначає макрос, який замінюється ще до початку компіляції. constпросто модифікує змінну, щоб компілятор позначив помилку, якщо ви спробуєте її змінити. Є контексти, в яких ти можеш використовувати a, #defineале ти не можеш використовувати a const(хоча я намагаюся знайти його, використовуючи останній дзвін). Теоретично a constзаймає місце у виконуваному файлі та вимагає посилання на пам'ять, але на практиці це незначно і може бути оптимізовано компілятором.
consts набагато зручніші для компілятора та налагоджувача, ніж #defines. У більшості випадків це найважливіший момент, який слід враховувати, приймаючи рішення, який із них використовувати.
Просто подумав про контекст, в якому ти можеш використовувати, #defineале ні const. Якщо у вас є константа, яку ви хочете використовувати у безлічі .cфайлів, #defineпросто додайте її в шапку. З a constви повинні мати визначення у файлі C та
const int MY_INT_CONST = 12345;
extern const int MY_INT_CONST;
у заголовку. MY_INT_CONSTне може використовуватися як розмір статичного або глобального масиву області в будь-якому файлі C, крім того, у якому він визначений.
Однак для цілочисельних констант можна використовувати enum. Насправді це те, що Apple робить майже незмінно. Це має всі переваги і #defines, і consts, але працює лише для цілочисельних констант.
enum
{
MY_INT_CONST = 12345,
};
Нарешті, який шлях є більш ефективним та / або більш безпечним?
#defineє більш ефективним в теорії, хоча, як я вже говорив, сучасні компілятори, ймовірно, впевнені, що різниці мало. #defineє більш безпечним, оскільки завжди намагається призначити йому помилку компілятора
#define FOO 5
FOO = 6;
consts можна обдурити, щоб їх було призначено, хоча компілятор може видавати попередження:
const int FOO = 5;
(int) FOO = 6;
Залежно від платформи, призначення може все-таки провалитися під час виконання, якщо константа розміщується в сегменті лише для читання, і це офіційно невизначена поведінка відповідно до стандарту C.
Особисто для цілочисельних констант я завжди використовую enums для констант інших типів, constякщо не маю поважних причин цього не робити.