Чи повинні оператори перемикання завжди містити за замовчуванням застереження?


254

В одному з моїх перших оглядів коду (деякий час назад) мені сказали, що в усіх операторах переключення є доброю практикою включити за замовчуванням. Нещодавно я згадав цю пораду, але не можу пригадати, яке виправдання було. Зараз це звучить для мене досить дивно.

  1. Чи є розумна причина завжди включати заявку за замовчуванням?

  2. Чи залежить ця мова? Я не пам'ятаю, якою мовою я користувався в той час - можливо, це стосується деяких мов, а не інших?


9
Це значною мірою залежатиме від мови
скафман

Відповіді:


276

Корпуси комутаторів майже завжди повинні мати defaultсправу.

Причини використання а default

1.Щоб "зловити" несподіване значення

switch(type)
{
    case 1:
        //something
    case 2:
        //something else
    default:
        // unknown type! based on the language,
        // there should probably be some error-handling
        // here, maybe an exception
}

2. Обробляти дії "за замовчуванням", коли випадки мають особливу поведінку.

Ви бачите це ЛОТ у програмах, керованих меню та скриптах bash shell. Ви також можете це побачити, коли змінна оголошена за межами регістру комутатора, але не ініціалізована, і кожен випадок ініціалізує її на щось інше. Тут за замовчуванням потрібно його ініціалізувати, щоб вниз код рядка, який звертається до змінної, не викликав помилку.

3. Показати комусь, хто читає ваш код, що ви охоплювали цю справу.

variable = (variable == "value") ? 1 : 2;
switch(variable)
{
    case 1:
        // something
    case 2:
        // something else
    default:
        // will NOT execute because of the line preceding the switch.
}

Це був надто спрощений приклад, але справа в тому, що хтось, читаючи код, не повинен дивуватися, чому variableне може бути щось інше, ніж 1 або 2.


Єдиний випадок, який я можу не використовувати, default- це коли перемикач перевіряє щось, де його досить очевидна будь-яка інша альтернатива може бути щасливо ігнорована

switch(keystroke)
{
    case 'w':
        // move up
    case 'a':
        // move left
    case 's':
        // move down
    case 'd':
        // move right
    // no default really required here
}

25
Ваш приклад щодо натискань клавіш суперечить решті сказаного. : | Я думаю, що трохи більше пояснень має сенс, таких як: вам не байдуже за замовчуванням в цьому випадку, тому що якщо натиснути іншу клавішу, то вам все одно, але якщо передача змінної відрізняється від очікуваної, нам все одно .
Андрій

1
У той же час, якщо ви перевіряєте параметр GET, ви, можливо, не хочете, щоб виняток викидався щоразу, коли користувач змінює URL-адресу отримання на щось, що недійсне: [
Андрій,

4
@Andrew WASD є загальним для рухів персонажів комп'ютерних ігор. Вам не знадобиться жодних дій за замовчуванням, оскільки інші ключі можуть бути призначені для інших взаємодій. У цьому виді перемикача корисно викликати функції руху.
jemiloii

13
Деякі компілятори попереджають під час увімкнення перерахунку, якщо справа пропущена, і додавання випадку за замовчуванням придушить це попередження. Зважаючи на те, що це, на мій досвід, дуже поширене джерело помилок (забувши оновити комутатор десь після додавання значення перерахунку), це здається дуже вагомою причиною пропустити випадок за замовчуванням.
rdb

3
@virusrocks Якщо ваш стан переживає, ви все одно можете мати неочікувані значення. Наприклад, якщо ви додаєте нове значення до enum, та забудьте оновити комутатор. Також в деяких мовах ви можете присвоїти цілі значення значенням перерахунків. У C ++ enum MyEnum { FOO = 0, BAR = 1 }; MyEnum value = (MyEnum)2;робить дійсний MyEnumекземпляр, який не дорівнює FOOабо BAR. Якщо будь-яка з цих проблем спричинить помилку у вашому проекті, випадок за замовчуванням допоможе вам знайти помилку дуже швидко, часто без налагодження!
cdgraham

54

Немає.

Що робити, якщо не існує дій за замовчуванням, важливий контекст. Що робити, якщо ви хочете діяти лише на кількох значеннях?

Візьмемо для прикладу читання натискань клавіш для гри

switch(a)
{
   case 'w':
     // Move Up
     break;
   case 's':
     // Move Down
     break;
   case 'a':
     // Move Left
     break;
   case 'd':
     // Move Right
     break;
}

Додавання:

default: // Do nothing

Це просто витрата часу і збільшує складність коду без причини.


14
Хороший приклад. Але насправді додавання за замовчуванням простого // do nothingкоментаря дає зрозуміти, що це "добре", якщо не всі випадки охоплені, на відміну від інших заяв комутатора, де це було б "не нормально".
Цвях

8
Ні. Кодування стосується не лише вирішення деяких справ. Також він служить документом. Написавши за замовчуванням: та коментуючи як // Не робіть нічого чи чогось іншого, читабельність коду стає кращою.
JongAm Park

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

Саме так. Це в тій самій концепції передачі al post params. Ви поводитесь з тими, про кого ви дбаєте, не з іншими.
Джиммі Кейн

2
@jybrd Якщо ви не довіряєте, що попередній розробник навмисно викинув за замовчуванням, то чому б ви довіряли правильності його введення? За замовчуванням може бути випадково порожнім так само просто, як і зовсім відсутні. Коментар не потрібен для чогось такого тривіального. Це безладність коду. Напишіть тести блоку повного покриття, щоб натомість показати свої наміри. (Просто моя думка)
Роберт Ноак

45

НЕ мати випадок за замовчуванням може бути корисним в деяких ситуаціях.

Якщо у випадках перемикання є значення перерахунків, не маючи випадку за замовчуванням, ви можете отримати попередження компілятора, якщо у вас відсутні випадки. Таким чином, якщо в майбутньому будуть додані нові значення enum, і ви забудете додати випадки цих значень до комутатора, ви можете дізнатися про проблему під час компіляції. Ви все ж переконайтеся, що код вживає відповідних дій для незроблених значень, у разі якщо недійсне значення було передано типу enum. Тож це може бути найкращим чином для простих випадків, коли ви можете повернутися у випадку перешкод, а не зламати.

enum SomeEnum
{
    ENUM_1,
    ENUM_2,
    // More ENUM values may be added in future
};

int foo(SomeEnum value)
{
    switch (value)
    {
    case ENUM_1:
        return 1;
    case ENUM_2:
        return 2;
    }
    // handle invalid values here
    return 0;
 }

Це важливе спостереження! Він більше застосовується в Java, тому що він не дозволяє викидати вставки до перерахунків.
Лій

2
У вашому прикладі ви можете кинути виняток замість повернення після оператора switch. Таким чином, ви могли б провести і статичну перевірку компілятором, і отримати явну помилку, якщо трапиться щось несподіване.
Лій

1
Я згоден. У Swift, наприклад, перемикач повинен бути вичерпним, інакше ви отримаєте помилку компілятора! Надання за замовчуванням просто заглушує цю корисну помилку. З іншого боку, надання за замовчуванням, якщо всі справи розглядаються насправді, кидає попередження компілятора (недоступне твердження).
Енді

1
Щойно виправлена ​​помилка, це призвело б до попередження компілятора, якби не було типових налаштувань: тому загалом для перемикання змінних перерахунків не повинно бути за замовчуванням.
нотан

42

Я б завжди використовував за замовчуванням, незалежно від того, якою мовою ви працюєте.

Все може й піти не так. Цінності не будуть такими, які ви очікуєте тощо.

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

Ось чому ви завжди повинні використовувати за замовчуванням статтю та видаляти помилку, наприклад у Java:

switch (myVar) {
   case 1: ......; break;
   case 2: ......; break;
   default: throw new RuntimeException("unreachable");
}

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


39
Я вважаю за краще, throw new RuntimeException("myVar invalid " + myVar);оскільки це може дати вам достатньо інформації, щоб розібратися та виправити помилку, не використовуючи налагоджувач та перевірити змінні, що може бути складно, якщо це рідко виникає проблема, яку важко відтворити.
Кріс Додд

1
Що робити, якщо це не помилка, щоб значення не відповідало одному із випадків?
Гейб

4
Якщо це не помилка, тоді не потрібно буде default:. Але частіше, ніж ні, людина залишає за замовчуванням, тому що думає, що myVarніколи не може мати ніякого значення, крім перерахованих; однак я не можу порахувати, скільки разів мене здивували в реальному житті, коли змінна мала значення, відмінне від значень, які вона "могла мати". У цих випадках я був вдячний за виняток, який змусив мене побачити це відразу, а не викликати пізніше якусь іншу помилку (складніше налагодження) або неправильну відповідь (можливо, я не помічую тестування).
Адріан Сміт

2
Я згоден з Адріаном. Невдача невдача і невдача рано.
Невдалий

Я вважаю за краще кидати AssertionErrorзамість цього RuntimeException, оскільки ця ситуація дуже схожа на твердження про те, що myVarце одне з оброблених значень. Також шанс того, що хтось застає та проковтне помилку, менший.
Філіп Вендлер

15

У моїй компанії ми пишемо програмне забезпечення для ринку Avionics and Defense, і ми завжди включаємо заяву за замовчуванням, оскільки ВСІ випадки в операторі перемикання повинні бути чітко оброблені (навіть якщо це лише коментар із повідомленням "Не робити нічого"). Ми не можемо дозволити собі програмному забезпеченню просто погано поводитись або просто розбиватися на несподівані (або навіть те, що ми вважаємо неможливим) значення.

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


1
У мене така ж вимога, де я працюю; ми пишемо код для вбудованих µControllers, які повинні пройти сувору перевірку безпеки та часто піддаються EMI. Було б безвідповідально вважати, що перелічена змінна ніколи не буде мати значення, яке відсутнє в списку перерахування.
oosterwal

12

Чи повинен оператор "switch" завжди містити за замовчуванням пункт? Ні , це повинно зазвичай включати в себе по замовчуванням.

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

Ось тривіальний приклад того, де немає сенсу:

void PrintSign(int i)
{
    switch (Math.Sign(i))
    {
    case 1:
        Console.Write("positive ");
        break;
    case -1:
        Console.Write("negative ");
        break;
    default: // useless
    }
    Console.Write("integer");
}

Це еквівалент:

void PrintSign(int i)
{
    int sgn = Math.Sign(i);
    if (sgn == 1)
        Console.Write("positive ");
    else if (sgn == -1)
        Console.Write("negative ");
    else // also useless
    {
    }
    Console.Write("integer");
}

Я не погоджуюсь. ІМХО, єдиний раз, коли за замовчуванням не повинно існувати, це якщо зараз і назавжди немає можливості змінити набір входів, і ви отримаєте всі можливі значення. Найпростіший випадок, який я можу придумати, - це булеве значення з бази даних, де єдині відповіді (до зміни SQL!) - істина, помилка та NULL. У будь-якому іншому випадку, маючи за замовчуванням твердження або виняток "Не повинно статися!" має добрий сенс. Якщо ваш код зміниться, і у вас є одне або більше нових значень, ви можете переконатися, що ви їх кодуєте, і якщо ви цього не зробите, ваші тести будуть підірвані.
Харпер Шелбі

4
@Harper: Ваш приклад підпадає під категорію "стверджувати про помилку".
Гейб

Я запевняю, що мій приклад є нормою, і виняток є невелика кількість випадків, коли можна бути на 100% впевненим, що кожен можливий випадок охоплюється, а дефолт не потрібен. Ваша відповідь сформульована таким чином, що це звучить (принаймні для мене) так, ніби за замовчуванням нічого не буде, це трапляється частіше, ніж ні.
Харпер Шелбі

@Harper: Гаразд, я змінив формулювання, щоб вказати на те, що ситуація "нічого робити" є менш поширеною.
Гейб

4
Я думаю, що default:в цих випадках кодифікується ваші припущення. Наприклад, чи нормально, коли sgn==0друкувати integer(ні позитивні, ні негативні), чи це помилка? Мені, читаючи цей код, важко сказати. Я припускаю, що ви хочете писати zeroв цьому випадку ні integer, і що програміст зробив припущення, що sgnможе бути лише -1 або +1. Якби це було так, наявність програми default:дозволила б програмісту рано засвоїти помилку припущення та змінити код.
Адріан Сміт

7

Наскільки я бачу, відповідь "за замовчуванням" є необов'язковою, кажучи, що перемикач завжди повинен містити типовий засіб, як те, що кожен "if-elseif" повинен містити "else". Якщо за замовчуванням має бути зроблена логіка, тоді слід встановити оператор 'default', але в іншому випадку код може продовжувати виконуватись, не роблячи нічого.


6

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

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

Зауважте, що "не слід досягти" означає, що якщо він досяг помилки в програмному забезпеченні - вам потрібно перевірити значення, які можуть містити небажані значення через введення користувачем тощо.


3
Ще одна поширена причина отримання несподіваних випадків: інші частини коду будуть змінені, можливо, через роки.
Хендрік Бруммерманн

Дійсно, це дуже небезпечна поведінка. Принаймні, я б додав пункт assort (). Тоді його легко виявити, коли є помилка.
Курт Паттін

5

Я б сказав, що це залежить від мови, але якщо ви перемикаєте тип перерахунку і обробляєте всі можливі значення, вам, мабуть, краще НЕ включати регістр за замовчуванням. Таким чином, якщо ви додасте додатковий тег enum пізніше і забудете додати його до комутатора, компетентний компілятор видасть вам попередження про відсутній випадок.


5
"Кожне можливе значення" навряд чи вдасться впоратися із перерахунками. Ви можете призначити ціле число до перерахунку, навіть якщо це конкретне значення чітко не визначено. І який компілятор попереджає про відсутню справу?
TrueWill

1
@TrueWill: Так, ви можете використовувати явні касти, щоб написати неясний код, який неможливо зрозуміти; щоб написати зрозумілий код, вам слід цього уникати. gcc -Wall(сорт найнижчого загального знаменника компетентних компіляторів) дає попередження про перерахунки, що не вживаються в операторах переключення.
Кріс Додд

4

Якщо ви знаєте, що оператор переключення завжди матиме чітко визначений набір міток або значень, просто зробіть це для покриття баз, таким чином ви завжди отримаєте дійсний результат. Просто поставте за замовчуванням над міткою, яка буде програмно / логічно бути найкращим обробником інших цінностей.

switch(ResponseValue)
{
    default:
    case No:
        return false;
    case Yes;
        return true;
}

Чи defaultпотрібна товста кишка після цього ще? Чи дозволяє це зробити якийсь спеціальний синтаксис, який дозволив вам опустити його?
Ponkadoodle

Товста кишка потрібна, це була друкарська помилка, дякую за те, що ви звернули її на мою увагу.
deegee

3

Принаймні, це не обов'язково на Java. За словами JLS, він говорить, що може бути принаймні одна справа за замовчуванням. Це означає, що жоден випадок за замовчуванням не прийнятний. Часом це також залежить від контексту, в якому ви використовуєте оператор switch. Наприклад, у Java для наступного блоку комутаторів не потрібен регістр за замовчуванням

private static void switch1(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        break;
    case "Tuesday":
        System.out.println("Tuesday");
        break;
    }
}

Але в наступному методі, який очікує повернення рядка, випадок за замовчуванням стане зручним, щоб уникнути помилок компіляції

    private static String switch2(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        return name;

    case "Tuesday":
        System.out.println("Tuesday");
        return name;

    default:
        return name;
    }
}

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


3

Деякі (застарілі) вказівки говорять так, як, наприклад, MISRA C :

Вимогою остаточного застереження за замовчуванням є захисне програмування. Ця стаття повинна або вжити відповідних дій, або містити відповідні коментарі щодо того, чому не вживаються дії.

Ця порада застаріла, оскільки вона не ґрунтується на релевантних критеріях. Яскравий пропуск - це те, що сказав Харлан Касслер:

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

Як показав Гарлан, функціональний еквівалент випадку за замовчуванням можна відтворити після вимикача. Що тривіально, коли кожен випадок - це раннє повернення.

Типовою потребою в динамічній перевірці є керування введеннями в широкому розумінні. Якщо значення надходить поза контролем програми, йому не можна довіряти.

Тут Місра також займає позицію екстремального оборонного програмування, і, якщо недійсне значення є фізично репрезентативним, його потрібно перевірити, незалежно від того, чи програма достовірно правильна. Що має сенс, якщо програмне забезпечення має бути максимально надійним за наявності апаратних помилок. Але, як сказав Офір Йоктан, більшість програмного забезпечення краще не "обробляти" помилки. Останню практику іноді називають образливим програмуванням .


2

Ви повинні мати за замовчуванням, щоб вибирати несподівані значення, що надходять.

Однак я не згоден з Адріаном Смітом, що ваше повідомлення про помилку за замовчуванням повинно бути чимось абсолютно безглуздим. Можливо, у випадку, коли ви не розглядали випадки, які ви не розглядали (що є суть), ваш користувач побачить, і повідомлення типу "недоступне" є абсолютно безглуздим і нікому не допомагає у цій ситуації.

Справа в тому, скільки разів у вас був абсолютно безглуздий BSOD? Або фатальний виняток @ 0x352FBB3C32342?


наприклад - пам’ятайте, що не лише розробник завжди бачить повідомлення про помилки. Ми живемо в реальному світі, люди роблять помилки.
Джон Хант

2

Якщо значення перемикача ( перемикача (змінної )) не може досягти випадку за замовчуванням, то випадок за замовчуванням взагалі не потрібен. Навіть якщо ми збережемо за замовчуванням, він взагалі не виконується. Це мертвий код.


2

Це необов'язкове кодування "конвенція". Залежно від використання залежить, потрібен він чи ні. Я особисто вважаю, що якщо вам це не потрібно, його не повинно бути там. Навіщо включати те, що користувач не буде використаний чи досягнутий?

Якщо можливості регістру обмежені (тобто булеві), тоді за замовчуванням додаток є зайвим !


2

Якщо у switchвикладі відсутній випадок за замовчуванням , поведінка може бути непередбачуваною, якщо такий випадок виникне в якийсь момент часу, що не було передбачувано на стадії розробки. Доброю практикою є включення defaultсправи.

switch ( x ){
  case 0 : { - - - -}
  case 1 : { - - - -}
}

/* What happens if case 2 arises and there is a pointer
* initialization to be made in the cases . In such a case ,
* we can end up with a NULL dereference */

Така практика може призвести до такої помилки, як затримка NULL , витік пам'яті , а також інші типи серйозних помилок .

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


2

Вибір за замовчуванням може не знадобитися в комутаторі, який використовується enum. коли перемикач містив все значення, випадок за замовчуванням ніколи не виконується. Так що в цьому випадку це не обов’язково.


1

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


1

Я не погоджуюсь з найбільш голосованою відповіддю Ванваріла вище.

Будь-який код додає складності. Для цього також потрібно зробити тести та документацію. Тож завжди добре, якщо можна програмувати, використовуючи менше коду. Моя думка полягає в тому, що я використовую за замовчуванням статтю для невичерпних операторів переключення, тоді як я не використовую за замовчуванням для вичерпних операторів переключення. Щоб бути впевненим, що я зробив це правильно, я використовую інструмент аналізу статичного коду. Тому давайте розберемося в деталях:

  1. Невичерпні оператори переключення: вони завжди повинні мати значення за замовчуванням. Як випливає з назви, це твердження, які не охоплюють усіх можливих значень. Це також може бути неможливим, наприклад, оператор перемикання на ціле значення або на String. Тут я хотів би скористатися прикладом Vanwaril (Слід зазначити, що я думаю, що він використав цей приклад, щоб зробити неправильну пропозицію. Я використовую його тут, щоб констатувати навпаки -> Використовувати твердження за замовчуванням):

    switch(keystroke)
    {
      case 'w':
        // move up
      case 'a':
        // move left
      case 's':
        // move down
      case 'd':
        // move right
      default:          
        // cover all other values of the non-exhaustive switch statement
    }
    

    Гравець може натиснути будь-яку іншу клавішу. Тоді ми нічого не могли зробити (це може бути показано в коді, просто додавши коментар до випадку за замовчуванням), або це, наприклад, слід надрукувати щось на екрані. Цей випадок є актуальним, оскільки може статися.

  2. Вичерпні висловлювання комутатора: Ці заяви перемикання охоплюють усі можливі значення, наприклад оператор перемикання для перерахунку типів системи класів. При розробці коду вперше легко охопити всі значення. Однак, оскільки ми люди, є невеликий шанс забути когось. Крім того, якщо ви додаєте значення перерахунку пізніше, так що всі оператори перемикання повинні бути адаптовані, щоб зробити їх вичерпними знову відкриває шлях до пекла помилок. Просте рішення - це інструмент аналізу статичного коду. Інструмент повинен перевіряти всі заяви комутатора та перевіряти, чи є вони вичерпними чи мають значення за замовчуванням. Ось приклад вичерпного твердження перемикача. Спочатку нам потрібен перерахунок:

    public enum GradeSystemType {System1To6, SystemAToD, System0To100}
    

    Тоді нам потрібна змінна цього перерахунку GradeSystemType type = .... Вичерпний вимикач заяви буде виглядати приблизно так:

    switch(type)
    {
      case GradeSystemType.System1To6:
        // do something
      case GradeSystemType.SystemAToD:
        // do something
      case GradeSystemType.System0To100:
        // do something
    }
    

    Отже, якщо ми розширимо на GradeSystemType, наприклад, System1To3інструмент аналізу статичного коду повинен виявити відсутність за замовчуванням застереження і оператор переключення не є вичерпним, тому ми економимо.

Просто одна додаткова річ. Якщо ми завжди використовуємо defaultпункт, може статися, що інструмент аналізу статичного коду не здатний виявляти вичерпні або невичерпні оператори перемикання, оскільки він завжди виявляє defaultзастереження. Це дуже погано, оскільки ми не будемо поінформовані, якщо розширимо перерахунок на інше значення і забудемо додати його до одного оператора переключення.


0

Чи повинні оператори перемикання завжди містити за замовчуванням застереження? Жодних випадків перемикання не може існувати з випадком за замовчуванням, у випадку вимикача випадок за замовчуванням у цьому випадку буде викликати значення комутатора switch(x)x, коли воно не збігається з будь-якими іншими значеннями регістру.


0

Я вважаю, що це досить специфічно для мови, і для випадку C ++ є другорядним моментом для enum class типу . Що видається більш безпечним, ніж традиційний C enum. АЛЕ

Якщо ви подивитеся на реалізацію std :: byte, це щось на зразок:

enum class byte : unsigned char {} ;

Джерело: https://en.cppreference.com/w/cpp/language/enum

А також врахуйте це:

В іншому випадку, якщо T - це тип перерахування, який має масштаб або не має рамки з фіксованим базовим типом, і якщо у списку з braced-init є лише один ініціалізатор, і якщо перетворення з ініціалізатора в базовий тип не звужує, і якщо ініціалізація - це прямий список-ініціалізація, тоді перерахування ініціалізується в результаті перетворення ініціалізатора в його базовий тип.

(оскільки C ++ 17)

Джерело: https://en.cppreference.com/w/cpp/language/list_initialization

Це приклад класу enum, що представляє значення, які не визначені нумератором. З цієї причини ви не можете покласти довіру до перерахунків. Залежно від застосування це може бути важливим.

Однак мені дуже подобається те, що сказав @Harlan Kassler у своєму дописі, і я сам розпочну використовувати цю стратегію в деяких ситуаціях.

Просто приклад класу небезпечних перерахунків:

enum class Numbers : unsigned
{
    One = 1u,
    Two = 2u
};

int main()
{
    Numbers zero{ 0u };
    return 0;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.