"Статичний const" проти "#define" проти "enum"


585

Який з них краще використовувати серед наведених нижче тверджень у С?

static const int var = 5;

або

#define var 5

або

enum { var = 5 };

35
Цікаво, що це майже те саме питання, що і stackoverflow.com/questions/1637332/static-const-vs-define . Єдина відмінність полягає в тому, що це питання стосується C ++, а це - про C. Оскільки моя відповідь була специфічною для C ++, я кажу, що це робить їх не тотожними, але інші можуть не погодитися.
ТЕД

53
Не тотожна, безумовно. Є ціла маса областей, де C ++ дозволяє синтаксис C з міркувань сумісності. У таких випадках питання на кшталт "що найкраще зробити X" матимуть різні відповіді на C ++. Наприклад, ініціалізація об'єкта
MSalters


Як це не на думці? У кожного вони різні цілі
Сем Хаммамі

1
@RobertSsupportsMonicaCellio, так. Дякую за залякування
Vijay

Відповіді:


690

Це залежить від того, для чого вам потрібне значення. Ви (і всі інші поки що) опустили третю альтернативу:

  1. static const int var = 5;
  2. #define var 5
  3. enum { var = 5 };

Ігноруючи питання щодо вибору імені, тоді:

  • Якщо вам потрібно провести вказівник навколо, ви повинні використовувати (1).
  • Оскільки (2), мабуть, варіант, вам не потрібно передавати вказівники навколо.
  • У таблиці символів налагоджувача (1) і (3) є символ - це полегшує налагодження. Більш ймовірно, що (2) не буде символу, залишаючи вам цікаво, що це таке.
  • (1) не може використовуватися як вимір для масивів у глобальному масштабі; і (2), і (3) можуть.
  • (1) не може використовуватися як розмір для статичних масивів в області функцій; і (2), і (3) можуть.
  • Під C99 все це можна використовувати для локальних масивів. Технічно використання (1) означало б використання VLA (масив змінної довжини), хоча розмірність, на яку посилається "var", звичайно, буде фіксована у розмірі 5.
  • (1) не може використовуватися в таких місцях, як заяви переключення; і (2), і (3) можуть.
  • (1) не можна використовувати для ініціалізації статичних змінних; і (2), і (3) можуть.
  • (2) може змінити код, який ви не хотіли змінити, оскільки він використовується препроцесором; і (1), і (3) не матимуть таких несподіваних побічних ефектів.
  • Ви можете виявити, чи було встановлено (2) у препроцесорі; ні (1), ні (3) цього не дозволяють.

Тож у більшості контекстів віддають перевагу "перерахунку" над альтернативами. В іншому випадку перша і остання точки кулі, ймовірно, будуть контролюючими факторами - і вам доведеться думати важче, якщо вам потрібно задовольнити обидва відразу.

Якщо ви запитували про C ++, то ви кожен раз використовували б варіант (1) - статичний const.


111
фантастичний список! Одним із недоліків enumє те, що вони реалізовані як int([C99] 6.7.2.2/3). #defineДозволяє визначити непідписані і довго з Uі Lсуфікси, і constдозволяє дати тип. enumможе спричинити проблеми з перетвореннями звичайного типу.
Готьє

37
(2) люди ВЖЕ нарікають на безпеку типу. Я ніколи не розумію, чому б не просто використовувати "#define var ((int) 5)" і ура, що ти маєш безпеку типу з визначенням.
Інго Блекмен

6
@RedX: Вам доведеться опинитися у дуже своєрідному середовищі, яке викликає проблему. Однак, ні, enumні #defineвикористовуйте додатковий простір. Значення відображатиметься в об'єктному коді як частина інструкцій, а не виділяється на зберігання в сегменті даних або в купі або в стеку. У вас буде виділено трохи місця для static const int, але компілятор може оптимізувати його, якщо ви не знайдете адресу.
Джонатан Леффлер

15
Ще одне «голосування» за enums (і static const): їх неможливо змінити. a defineможе бути #undefine'd, де enumі static constзакріплене за заданим значенням.
Даан Тіммер

15
@QED: Ні, дякую. Проста константа є безпечною поза дужками. Або покажіть мені, як програма, яку можна було б законно очікувати для компіляції, буде змінена, не маючи 5 в дужках. Якби це був аргумент макросу стилю функції або якщо в виразі були якісь оператори, то ви вірно звинувачуєте мене, якби я не включив дужки. Але це не так.
Джонатан Леффлер

282

Загалом:

static const

Тому що він поважає сферу застосування та є безпечним для типу.

Єдине застереження, яке я міг бачити: якщо ви хочете, щоб змінна була визначена в командному рядку. Є ще альтернатива:

#ifdef VAR // Very bad name, not long enough, too general, etc..
  static int const var = VAR;
#else
  static int const var = 5; // default value
#endif

По можливості замість макросів / еліпсисів використовуйте безпечну альтернативу.

Якщо ви дійсно НЕОБХІДНО переходити з макросом (наприклад, ви хочете __FILE__або __LINE__), то вам краще назвати свій макрос ДУЖЕ ретельно: у його імені про назву Boost рекомендує всі великі регістри, починаючи з назви проекту (тут BOOST_ ), переглядаючи бібліотеку, ви помітите, що після цього (як правило) слідує назва конкретної області (бібліотеки), а потім змістовна назва.

Зазвичай це стосується довгих імен :)


2
Погоджено - також із #define існує загальна небезпека керування кодом, оскільки препроцесор не знає синтаксису.
NeilDurant

10
Краще використовувати #if, ніж #ifdef, але в іншому випадку я згоден. +1.
Tim Post

58
Це стандартна євангелізація C ++. Відповідь нижче набагато зрозуміліше в поясненні того, які варіанти є насправді і означають. Зокрема: у мене просто була проблема зі «статичним const». Хтось використовував це для визначення близько 2000 "констант" у файлі заголовка. Тоді цей заголовок був включений у близько 100 ".c" та ".cpp" файлів. => 8 Мбайт для "consts". Чудово. Так, я знаю, що ви можете використовувати лінкер для видалення невизначених consts, але це все одно залишає вас, які "consts", на які посилаються. Не вистачає місця, що в цій відповіді все не так.
Інго Блекмен

2
@IngoBlackman: з хорошим компілятором staticзалишаються лише ті , адреса яких взята; і якщо адреса взята, ніхто не міг би використовувати #defineабо enum(без адреси) ... тож я дійсно не розумію, яку альтернативу можна було б використати. Якщо ви можете усунути "оцінку часу компіляції", ви можете шукати extern constнатомість.
Матьє М.

15
@Tim Post: #ifможе бути кращим #ifdefдля булевих прапорів, але в цьому випадку неможливо визначити varяк 0з командного рядка. Тож у цьому випадку #ifdefмає більше сенсу, якщо 0це юридична цінність var.
Маартен

108

В, конкретно? В C правильна відповідь: використовувати #define(або, якщо потрібно, enum)

Незважаючи на те, що корисно мати властивості розміщення та введення тексту в constоб'єкті, насправді constоб'єкти в C (на відміну від C ++) не є істинними константами і тому зазвичай є марними у більшості практичних випадків.

Отже, в С вибір повинен визначатися тим, як ви плануєте використовувати свою константу. Наприклад, ви не можете використовувати const intоб'єкт як caseмітку (хоча макрос буде працювати). Ви не можете використовувати const intоб'єкт як ширину бітового поля (поки макрос працюватиме). У C89 / 90 ви не можете використовувати constоб'єкт для визначення розміру масиву (поки макрос буде працювати). Навіть у C99 ви не можете використовувати constоб'єкт для визначення розміру масиву, коли вам потрібен масив, який не VLA .

Якщо це важливо для вас, то це визначить ваш вибір. Більшу частину часу у вас не буде іншого вибору, крім використання #defineв C. І не забувайте про іншу альтернативу, яка виробляє справжні константи в C - enum.

У C ++ constоб'єкти - це справжні константи, тому в C ++ майже завжди краще віддати перевагу constваріанту ( staticхоча в C ++ немає явного ).


6
"ви не можете використовувати об'єкт const int як мітку справи (поки макрос буде працювати)" ---> З приводу цього твердження я перевірив змінну const int в C в коммутаторі - справа працює ....
john

8
@john: Ну, вам потрібно надати тестований код та назвати конкретний компілятор. Використання const intоб'єктів у регістрі мови є незаконним у всіх версіях мови C. (Звичайно, ваш компілятор може підтримувати це як нестандартне розширення мови на C ++.)
1212 року

11
"... і тому зазвичай марні в більшості практичних випадків ." Я не погоджуюсь. Вони абсолютно корисні до тих пір, поки вам не потрібно використовувати ім'я як постійний вираз. Слово "константа" в C означає щось, що можна оцінити під час компіляції; constозначає лише для читання const int r = rand();є абсолютно законним.
Кіт Томпсон,

У c ++ його краще використовувати constexprпорівняно constз stlконтейнерами типу arrayабо bitset.
Маюх Саркар

1
@john, ви, мабуть, перевірили в switch()заяві, а не в caseодній. Мене щойно зачепило за це ☺
Привіт-Ангел

32

Різниця між static constі #defineполягає в тому, що перший використовує пам'ять, а пізніший не використовує пам'ять для зберігання. По-друге, ви не можете передавати адресу, #defineтоді як ви можете передавати адресу static const. Насправді, залежно від того, під якою обставиною ми знаходимось, нам потрібно вибрати одну з цих двох. Обидва в найкращих випадках за різних обставин. Будь ласка, не вважайте, що один кращий за інший ... :-)

Якби це було так, Денніс Річі залишив би найкращого в спокої ... ха-ха ... :-)


6
+1 для згадування пам’яті, деякі вбудовані системи все ще не так вже й багато, хоча, мабуть, я б почав використовувати статичні consts і лише змінити на #defines, якщо потрібно.
fluffyben

3
Я просто тестував це. Дійсно, const int використовує додаткову пам'ять порівняно з #define або enum. Оскільки ми програмуємо вбудовані системи, ми не можемо дозволити собі додаткове використання пам'яті. Отже, ми повернемось до використання #define або enum.
Девід Андреа

2
Практично кажучи, це неправда (більше), що constдійсно використовує пам'ять. GCC (тестований з 4.5.3 та кількома новішими версіями) легко оптимізує const intпрямий літерал у вашому коді при використанні -O3. Отже, якщо ви займаєтеся розробкою вбудованої оперативної пам'яті з низьким рівнем оперативної пам'яті (наприклад, AVR), ви можете сміливо використовувати C consts, якщо ви використовуєте GCC або інший сумісний компілятор. Я не перевіряв цього, але очікую, що Кланг зробить те ж саме, до речі.
Рафаель

19

У С #defineнабагато популярніший. Ви можете використовувати ці значення для оголошення розмірів масивів, наприклад:

#define MAXLEN 5

void foo(void) {
   int bar[MAXLEN];
}

ANSI C не дозволяє вам використовувати static consts в цьому контексті, наскільки я знаю. У C ++ вам слід уникати макросів у цих випадках. Можна писати

const int maxlen = 5;

void foo() {
   int bar[maxlen];
}

і навіть відмовитися, staticтому що внутрішній зв'язок мається на увазі constвже [лише для C ++].


1
Що ви маєте на увазі під «внутрішнім зв’язком»? Я можу мати const int MY_CONSTANT = 5;один файл і отримати доступ до нього extern const int MY_CONSTANT;в іншому. Я не зміг знайти будь-якої інформації в стандарті (принаймні C99) про constзміну поведінки за замовчуванням "6.2.2: 5 Якщо оголошення декларатора ідентифікатора для об'єкта має логічний обсяг і немає специфікатора класу зберігання, його зв'язок зовнішня".
Готьє

@Gauthier: Вибачте з цього приводу. Я мав би сказати, що "мається на увазі під const вже мовою C ++". Це специфічно для C ++.
sellibitze

@sellibitze Приємно бачити деякі аргументи по дорозі замість тонн ДУМКИ Якщо б був бонус за справжні аргументи, ти це отримав!
Поль

1
Станом на C99, ваш другий фрагмент є законним. barє VLA (масив змінної довжини); компілятор, ймовірно, генерує код так, ніби його довжина була постійною.
Кіт Томпсон,

14

Ще одним недоліком constC є те, що ви не можете використовувати значення для ініціалізації іншого const.

static int const NUMBER_OF_FINGERS_PER_HAND = 5;
static int const NUMBER_OF_HANDS = 2;

// initializer element is not constant, this does not work.
static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND 
                                     * NUMBER_OF_HANDS;

Навіть це не працює з const, оскільки компілятор не сприймає це як константу:

static uint8_t const ARRAY_SIZE = 16;
static int8_t const lookup_table[ARRAY_SIZE] = {
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!

Я б радий використовувати введені constв цих випадках, інакше ...


5
Трохи запізнився до гри, але це питання виникло в іншому питанні. Переслідування, чому ваш static uint8_t const ARRAY_SIZE = 16;раптом більше не компілюється, може бути дещо складним, особливо коли #define ARRAY_SIZE 256заглиблений десять шарів глибоко в заплутану павутину заголовків. Це ім'я всіх шапок ARRAY_SIZEзадає проблеми. Зарезервуйте ALL_CAPS для макросів і ніколи не визначайте макрос, який відсутній у формі ALL_CAPS.
Девід Хаммен

@David: обгрунтована порада, яку я буду дотримуватися.
Готьє

1
Через 4 роки ти врятував мені багато часу, з'ясовуючи, чому я не можу "гніздитися" const. На це можна було б звернути увагу більше!
Plouff

11

Якщо ви зможете піти від цього, static constмає масу переваг. Він підпорядковується нормальним принципам сфери застосування, видно в налагоджувальній машині і, як правило, підкоряється правилам, яким керуються змінні.

Однак, принаймні в оригінальному стандарті C, це насправді не є постійною. Якщо ви використовуєте #define var 5, ви можете писати int foo[var];як декларацію, але ви не можете цього зробити (за винятком як розширення компілятора "з static const int var = 5;. Це не так у C ++, де static constверсія може використовуватися де завгодно #defineверсія, і я вірю в це так само і з C99.

Однак ніколи не називайте #defineконстанту з малим іменем. Це скасує будь-яке можливе використання цього імені до кінця одиниці перекладу. Макроконстанти повинні бути в тому, що фактично є їхнім власним простором імен, а це традиційно всі великі літери, можливо, з префіксом.


6
На жаль, це не так з C99. constу C99 все ще не є реальною константою. Ви можете оголосити розмір масиву за допомогою constC у C99, але тільки тому, що C99 підтримує масиви змінної довжини. З цієї причини він працюватиме лише там, де дозволені VLA. Наприклад, навіть у C99 ви все одно не можете використовувати a constдля оголошення розміру масиву члена у struct.
ANT

Незважаючи на те, що C99 не дозволить вам це зробити, GCC (протестовано з 4.5.3) прекрасно дозволить вам ініціалізувати масиви з const intрозміром, як якщо б це був C ++ const або макрос. Незалежно від того, чи хочете ви залежати від цього відхилення GCC від стандарту - це, звичайно, ваш вибір, я особисто піду з цим, якщо ви дійсно не можете передбачити, використовуючи інший компілятор, ніж GCC або Clang, останній має ту саму особливість (протестований з Clang 3.7).
Рафаель

7

ЗАВЖДИ краще використовувати const, а не #define. Це тому, що const обробляється компілятором, а #define - препроцесором. Це як би #define сам по собі не є частиною коду (грубо кажучи).

Приклад:

#define PI 3.1416

Компілятори ніколи не можуть побачити символічну назву PI; Препроцесор може бути видалений ще до того, як вихідний код навіть потрапить до компілятора. Як результат, ім'я PI може не потрапити до таблиці символів. Це може заплутати, якщо ви отримаєте помилку під час компіляції, пов’язану з використанням константи, оскільки повідомлення про помилку може стосуватися 3.1416, а не PI. Якби PI був визначений у файлі заголовка, який ви не писали, ви б не мали уявлення, звідки цей 3.1416.

Ця проблема також може вирішитись у символьному відладчику, оскільки, знову ж таки, ім'я, з яким ви програмуєте, може не знаходитися в таблиці символів.

Рішення:

const double PI = 3.1416; //or static const...

6

#define var 5доставить вам неприємності, якщо у вас є такі речі mystruct.var.

Наприклад,

struct mystruct {
    int var;
};

#define var 5

int main() {
    struct mystruct foo;
    foo.var = 1;
    return 0;
}

Препроцесор замінить його, і код не буде компілюватися. З цієї причини традиційний стиль кодування пропонує всім постійним #defines використовувати великі літери, щоб уникнути конфлікту.


6

Я написав швидку програму тестування, щоб продемонструвати одну різницю:

#include <stdio.h>

enum {ENUM_DEFINED=16};
enum {ENUM_DEFINED=32};

#define DEFINED_DEFINED 16
#define DEFINED_DEFINED 32

int main(int argc, char *argv[]) {

   printf("%d, %d\n", DEFINED_DEFINED, ENUM_DEFINED);

   return(0);
}

Це компілюється з цими помилками та застереженнями:

main.c:6:7: error: redefinition of enumerator 'ENUM_DEFINED'
enum {ENUM_DEFINED=32};
      ^
main.c:5:7: note: previous definition is here
enum {ENUM_DEFINED=16};
      ^
main.c:9:9: warning: 'DEFINED_DEFINED' macro redefined [-Wmacro-redefined]
#define DEFINED_DEFINED 32
        ^
main.c:8:9: note: previous definition is here
#define DEFINED_DEFINED 16
        ^

Зауважте, що перерахунок дає помилку, коли визначення визначає попередження.


4

Визначення

const int const_value = 5;

не завжди визначає постійне значення. Деякі компілятори (наприклад, tcc 0.9.26 ) просто виділяють пам'ять, ідентифіковану з іменем "const_value". Використовуючи ідентифікатор "const_value", ви не можете змінювати цю пам'ять. Але ви все одно можете змінити пам'ять за допомогою іншого ідентифікатора:

const int const_value = 5;
int *mutable_value = (int*) &const_value;
*mutable_value = 3;
printf("%i", const_value); // The output may be 5 or 3, depending on the compiler.

Це означає визначення

#define CONST_VALUE 5

це єдиний спосіб визначити постійне значення, яке неможливо змінити жодним чином.


8
Модифікація постійного значення за допомогою вказівника є невизначеним поведінкою. Якщо ви хочете туди поїхати, #defineможна також змінити, відредагувавши машинний код.
ugoren

Ви частково праві. Я перевірив код за допомогою Visual Studio 2012 і він друкує 5. Але його неможливо змінити, #defineоскільки це макрос препроцесора. Його не існує у двійковій програмі. Якщо хтось хотів змінити всі місця, де CONST_VALUEвикористовувався, треба було це зробити по одному.
користувач2229691

3
@ugoren: Припустимо, ви пишете #define CONST 5, і тоді if (CONST == 5) { do_this(); } else { do_that(); }компілятор усуває elseгілку. Як ви пропонуєте змінити машинний код, щоб змінити його CONSTна 6?
Кіт Томпсон,

@KeithThompson, я ніколи не говорив, що це можна зробити легко і надійно. Просто #defineце не кулезахисне.
угорен

3
@ugoren: Моя думка полягає в тому, що "редагування машинного коду" не є розумним способом дублювання ефекту зміни значення a #define. Єдиний реальний спосіб зробити це - редагувати вихідний код і перекомпілювати.
Кіт Томпсон,

4

Хоча питання стосувалося цілих чисел, варто зазначити, що #define та enums марні, якщо вам потрібна константна структура чи рядок. Обидва вони передаються функціям як покажчики. (Для струн це потрібно; для структур це набагато ефективніше.)

Що стосується цілих чисел, якщо ви перебуваєте у вбудованому середовищі з дуже обмеженою пам’яттю, вам може знадобитися турбуватися про те, де зберігається константа та як збирається доступ до неї. Компілятор може додати два consts під час виконання, але додати два #defines під час компіляції. Константа #define може бути перетворена в одну або кілька інструкцій MOV [негайних], що означає, що константа ефективно зберігається в пам'яті програми. Константа const буде збережена в розділі .const в пам'яті даних. У системах з гарвардською архітектурою можуть бути відмінності у продуктивності та використанні пам’яті, хоча вони, ймовірно, невеликі. Вони можуть мати значення для жорсткої оптимізації внутрішніх циклів.


3

Не думайте, що є відповідь "що завжди найкраще", але, як сказав Матьє

static const

є безпечним для типу. #defineХоча мій найбільший улюбленець домашнього улюбленця , при налагодженні у Visual Studio ви не можете спостерігати за змінною. Це дає помилку, що символ неможливо знайти.


1
"Ви не можете переглянути змінну" Правильно, це не змінна. Це не змінюється, навіщо це потрібно дивитися? Ви можете знайти всюди, де він використовується просто шляхом пошуку етикетки. Навіщо вам потрібно (або навіть хотіти) переглянути #define?
Маршалл Юбанкс

3

Між іншим, альтернативою #define, яка забезпечує належне оцінювання, але поводиться як "справжня" константа, є "перерахунок". Наприклад:

enum {number_ten = 10;}

У багатьох випадках корисно визначати перелічені типи та створювати змінні цих типів; якщо це зроблено, налагоджувачі можуть мати змогу відображати змінні відповідно до назви їх перерахування.

Однак важливий застереження щодо цього: у C ++ перелічені типи мають обмежену сумісність із цілими числами. Наприклад, за замовчуванням не можна виконувати арифметику над ними. Я вважаю це цікавою поведінкою за замовчуванням для переліків; хоча було б непогано мати тип "суворого перерахунку", враховуючи бажання мати C ++, як правило, сумісний із C, я вважаю, що поведінка типу "enum" за замовчуванням має бути взаємозамінною з цілими числами.


1
У C константи перерахування завжди є типовими int, тому "haum enum" не можна використовувати з іншими цілими типами. (Перерахування типу поєднає з деяким визначається реалізацією цілого типу, не обов'язково int, але в цьому випадку типу є анонімним , так що не має значення.)
Кіт Томпсон

@KeithThompson: Оскільки я писав вище, я прочитав, що MISRA-C буде пробиватися, якщо компілятор призначить тип, відмінний від intзмінної типу переліку (які компілятори дозволено робити) і намагається призначити такій змінній член власного перерахунку. Я хотів би, щоб комітети зі стандартів додали портативні способи оголошення цілих типів із заданою семантикою. БУДЬ-яка платформа, незалежно від charрозміру, повинна мати можливість, наприклад, оголосити тип, який охоплює мод 65536, навіть якщо компілятор повинен додати багато AND R0,#0xFFFFчи еквівалентних інструкцій.
supercat

Ви можете використовувати uint16_t, хоча, звичайно, це не тип перерахування. Було б добре , щоб дозволити користувачеві вказати тип цілого числа , який використовується для подання даного типу перерахування, але ви можете багато чого домогтися того ж ефекту з typedefдля uint16_tі серії #defineз для окремих значень.
Кіт Томпсон,

1
@KeithThompson: Я розумію, що з історичних причин ми застрягли у тому, що деякі платформи оцінюватимуть 2U < -1Lяк істинне, а інші - як хибне, і тепер ми застрягли у тому, що деякі платформи реалізують порівняння між uint32_tі int32_tяк підписано а деякі - непідписані, але це не означає, що Комітет не міг визначити вищезмінного наступника C, який включає типи, семантика яких була б узгодженою для всіх компіляторів.
supercat

1

Проста різниця:

На час попередньої обробки константа замінюється її значенням. Таким чином, ви не можете застосувати оператор перенаправлення до визначення, але ви можете застосувати оператор розвідки до змінної.

Як ви вважаєте, визначити швидше, ніж статичний const.

Наприклад, маючи:

#define mymax 100

не можна робити printf("address of constant is %p",&mymax);.

Але маючи

const int mymax_var=100

ви можете зробити printf("address of constant is %p",&mymax_var);.

Для більш чіткого визначення, на етапі попередньої обробки дефініція замінюється його значенням, тому у нас немає жодної змінної, що зберігається в програмі. У нас є лише код з текстового сегмента програми, де було використано визначення.

Однак для статичного const у нас є змінна, яка десь виділяється. Для gcc статичний const виділяється в текстовому сегменті програми.

Вище я хотів розповісти про опорному операторі, тому замініть дереференцію на посилання.


1
Ваша відповідь дуже неправильна. Це стосується C, ваша відповідь стосується C ++, який має дуже різну семантику для constкласифікатора. C не має символічних констант, окрім констант . A const int- змінна. Ви також плутаєте мову та конкретні реалізації. Немає вимоги, де розмістити об’єкт. І це навіть не стосується gcc: зазвичай він розміщує constкваліфіковані змінні у .rodataрозділі. Але це залежить від цільової платформи. І ви маєте на увазі адресу оператора &.
занадто чесний для цього сайту

0

Ми розглянули створений код асемблера на MBF16X ... Обидва варіанти призводять до того ж коду для арифметичних операцій (наприклад, негайне додавання, наприклад).

Тому const intвважається кращим для перевірки типу, поки #defineце старий стиль. Можливо, це специфічно для компілятора. Тому перевірте свій створений код асемблера.


-1

Я не впевнений, чи маю рацію, але, на мою думку, виклик #defineзначення d набагато швидше, ніж виклик будь-якої іншої нормально оголошеної змінної (або значення const). Це тому, що коли програма працює і їй потрібно використовувати якусь звичайно оголошену змінну, їй потрібно перейти на точне місце в пам'яті, щоб отримати цю змінну.

Навпаки, коли вона використовує #defineзначення d, програмі не потрібно переходити до будь-якої виділеної пам'яті, вона просто приймає значення. Якщо #define myValue 7і програма викликає myValue, вона поводиться точно так само, як коли вона просто дзвонить 7.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.