Максимальное количество случаев, которые могут быть устранены с помощью оператора switch

Это из любопытства. Какое максимальное количество случаев переключения я могу иметь в одном коммутаторе, включая случай по умолчанию:. Я имею в виду вот так:

switch(ch)
{
case 1:
//some statement
break;
case 2: 
//some statement
break;
.
.
.
.
case n:
//some statement
break;
default:
//default statement
}

Мой вопрос: какое максимальное значение мы можем здесь иметь? Хотя это не является программно значимым, я нашел это довольно интригующей мыслью. Я искал некоторые блоги и нашел выражение здесь.

Из документа, который у меня есть, сказано, что:

Стандарт C указывает, что коммутатор может иметь не менее 257 случаев заявления. Стандарт С++ рекомендует не менее 16384 случая заявления поддерживаются! Реальная стоимость должна быть реализацией зависимыми.

Но я не знаю, насколько точна эта информация, может кто-нибудь дать мне идею? Также, что это означает, зависит от реализации? Предположим, что существует такой предел, можно ли каким-то образом изменить его на более высокое или меньшее значение?

Ответ 1

черновик стандарта С++ Annex B (informative) Implementation quantities говорит (основное внимание):

Поскольку компьютеры конечны, реализации С++ неизбежно ограничены в размерах программ, которые они могут успешно обрабатывать. Каждая реализация должна документировать те ограничения, которые известны. [...]

Пределы могут ограничивать количества, которые включают в себя описанные ниже или другие. Число в скобках после каждой величины рекомендуется как минимум для этой величины. Однако эти величины являются только рекомендациями и не определяют соответствие.

и включает следующий элемент:

- Ярлыки case для оператора switch (за исключением тех, которые содержатся для любых вложенных операторов switch) [16384].

но это не является жестким пределом только рекомендации по минимумам.

Реализация - это компилятор, стандартная библиотека и вспомогательные инструменты, и поэтому реализация зависит в основном для этого случая, когда компилятор решит, что такое предел, но он должен документировать этот предел. Проект стандарта определяет поведение, определяемое реализацией, в разделе 1.3.10 как:

для хорошо сформированной программы и правильных данных, которая зависит от реализации и что каждый документ реализации

Мы видим, что gcc не налагает ограничение для C:

GCC ограничен только доступной памятью.

который должен также охватывать С++ в этом случае и выглядит как Visual Studio также не устанавливает предел:

Microsoft C не ограничивает количество значений case в инструкции switch. Номер ограничен только доступной памятью. ANSI C требует, чтобы в инструкции переключателя допускалось не менее 257 меток ярлыков.

Я не могу найти подобную документацию для clang.

Ответ 2

В ваш вопрос помечен С++, поэтому на С++ 98 Приложение B/1:

Поскольку компьютеры конечны, реализации С++ неизбежно ограниченные по размеру программ, которые они могут успешно обработать. Каждая реализация должна документировать те ограничения, которые известны. Эта документация может ссылаться на фиксированные пределы, где они существуют, например, как вычислить переменные пределы как функцию доступных ресурсов или сказать что фиксированные пределы не существуют или неизвестны.

И затем Приложение B/2:

Пределы могут ограничивать количества, которые включают в себя описанные ниже или другие. Рекомендуется использовать число в скобках после каждого количества. как минимум для этой величины. Однако эти количества рекомендации и не определяют соответствия.

Итак, до тех пор, пока документация по внедрению делает то, что делает, допускается любое максимальное количество операторов case. Однако стандарт рекомендует 16384 в следующем списке.

Ответ 3

В стандарте c99, раздел 5.2.4.1 Ограничения на перевод:

Реализация должна иметь возможность переводить и выполнять по меньшей мере одну программу, которая содержит хотя бы один экземпляр каждого из следующих пределов: 13)

и включает в себя следующую строку:

- 1023 ярлыков case для оператора switch (исключая те для любого вложенного переключателя заявления)

В стандарте на С++ 98, Annex B (informative) Implementation quantities говорит:

Пределы могут ограничивать количества, которые включают в себя описанные ниже или другие. Рекомендуется использовать число в скобках после каждого количества. как минимум для этой величины. Однако эти количества рекомендации и не определяют соответствия.

- Ярлыки case для оператора switch (исключая те для любого вложенного switch) [16 384].

Ответ 4

Зависимость от реализации, поведение не определяется стандартом, это решение компилятора. Стандарт С++ не устанавливает минимальное значение для количества меток, которые оператор switch должен поддерживать.

Ответ 5

Теоретически максимальное число случаев, которые может иметь оператор switch, зависит от типа данных используемой переменной:

data_type x

switch(x)
{
...
}

для char, у вас 256, для коротких у вас есть 65536... и так далее; максимальное количество значений, которое вы можете представить, учитывая, что data_type.

Однако компилятор должен сгенерировать код для этого переключателя (оператора), а для кода, который он обычно генерирует, это что-то вроде

cmp(R1,$value)
IFT jmp _subroutine
cmp(R1,$value2)
IFT jmp _subroutine2
...

Чем больше случаев вы добавляете, тем выше давление на регистры и тем больше размер кода. Поскольку память и регистры не являются бесконечными, а компилятор написан на людях, должен быть предел - и это то, что подразумевается под implementation dependent. Каждый компилятор может разрешить разное количество случаев для оператора switch.