powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Очень интересны нюанс с оператором switch
25 сообщений из 236, страница 6 из 10
Очень интересны нюанс с оператором switch
    #39984486
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

Современная Java хранит строки чуть сложнее. У строки уже есть 2 варианта хранения. При едином интерфейсе снаружи.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984493
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
Угу.
Правда от константы для charat они все равно не отказались.
Им самим это больно было бы.
И боролись там не за скорость, а за память.

Нюанс состоит в том, что всяка ява/basic исходит из того, что строка уже есть .
И за всяки плюшки, сорта длины строки или её хеш-кода уже заплачено к моменту,
когда пришло время за константу обращаться к её символам или определять длину/хеш-код.

Между тем, есть масса задач, для которых представление строки "стандартным" библиотечным типом - это слишком дорогой платеж за её построение.

Из этого не следует, что не требуется опознавать текущий символ в каком-нибудь CharSequence,
или даже опознавать в нём целый набор отслеживаемых слов.

Но топик, вообще-то имени switch.
Прочитал на днях, что уже после первой стандартизации ANSI ещё какое время goto case 5:
признавали за легальную, но не рекомендуемую конструкцию.

Потом зачем-то решили разделить метки на правые и левые.
Конструкция goto case 5: при таком разделении оказалась левой.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984501
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
petrav,

Современная Java хранит строки чуть сложнее. У строки уже есть 2 варианта хранения. При едином интерфейсе снаружи.

А что возвращает оператор [] у Ява String?

PS: Если вам не интересно, то не отвечайте.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984503
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav

Вот в Европе какой процент программистов перед вызовом [] резко остановится и начнёт думать, а что там такое записано? Может суррогатная пара? Вот какой процент по вашему мнению? Я понимаю, что в вэбе это редко нужно.


Дональд Кнут считает что нужно сначала писать правильную и работающую
программу. А потом ее уже оптимизировать.

Моя точка зрения с этим вобщем совпадает. Ты должен в первую очередь прототипировать задачу.
Решать ее в виде теч-демо и предлагать заказчику. Дальнейшие улучшения - это технические дебты
которые можно пустить отдельной категорией. Разумеется я трачу время на обдумывание алгоритмов и
структур данных. Но поверь я ни секунды не думаю над строками. Их API в моих языках вылизан десятилетиями
и как правило он лучше чем я о нем думаю. Интринзики на ассемблере давно покрыли все строковые
операции типа compare, substing, indexOf e.t.c. даже в Java. Ну нету сегодня ни одного основания
думать о том как реализован get(i) для i-го символа. Он - константа уверяю тебя.

Все о чем писал Василий в части Unicode стандартов - это правильно. Другое дело что это правильно
в каком-то узком диапазоне кейсов. Я работал и DeucheBank и уверяю тебя ни секунды у меня не было
багов с нормализацией. Да я просто не ведал что это такое. Весь контент в Excel файлов и в базах
данных мы получали обычным utf-8 или unicode-16. И символы немецкого языка были в виде
ä, ö, ü (0x0228, 0x0246, 0x0252) односимвольных букв. Возможно немцы сами никогда
не используют эти combining characters или нам просто везло.

Попробуй полазить по немецким сайтам и посмотреть как отдается веб-содержимое. Найдешь хоть один
комбо-символ?
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984509
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
mayton
petrav,

Современная Java хранит строки чуть сложнее. У строки уже есть 2 варианта хранения. При едином интерфейсе снаружи.

А что возвращает оператор [] у Ява String?

PS: Если вам не интересно, то не отвечайте.

Давай глянем. В последней транковой версии исходников OpenJDK.
Почему я беру именно эту версию? Это эстраполяция на будущие разработки. То что входит
в эту ветку потом релизится.

remote.origin.url=https://github.com/unofficial-openjdk/openjdk

Вот вобщем 2 разных реализации. Для UTF16 и латиницы.

src/java.base/share/classes/java/lang/String.java
Код: java
1.
2.
3.
4.
5.
6.
7.
 public char charAt(int index) {
        if (isLatin1()) {
            return StringLatin1.charAt(value, index);
        } else {
            return StringUTF16.charAt(value, index);
        }
    }


Operator[] отсуствует. Тоесть он есть но определён только для массивов. Перегрузку индексатора
для произвольного класса java не поддерживает. Java - это достаточно консервативный язык.
Те кто хотят синтаксических сахаров - идут в Scala/Kotlin. И получают более мощный ЯП но в принципе
байткод тот-же самый. Местами байткод будет хуже т.к. подтянет больше зависимостей.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984512
ВсеРазумный
ВсеРазумный
Для обычного switch это goto array pointer address.


Ну это в лучшем случае, при хорошем оптимизаторе. А так - да, может быть так что switch обычный будет перебираться пока не найдёт свой собственный элемент конструкцией else-If.

Так что вы были не далеки от правды.

и чё если там миллионы их
и всё это в цикле?
да это противоречит всей философии C/C++, где именно на программисте лежит ответственность за то, где он что разместит. Невозможность убрать такой неэффективный поиск - это какой-то нонсенс.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984515
petrav
ВсеРазумный
petrav,

Просто в тексте поиска заменяйте Й,И,E,Ё на X и в искаемом тексте. Проблемы не будет

Я собственно это и предлагаю. Просто Сидоров рассуждает так: UC-32 нам не подходит, потому что нам всё равно нужны составные символы для поиска. Типа для поиска нужно Ё заменить на два символа. И пока он не смог обосновать зачем это нужно.

а тут предлагается английский текст искать русскими буквами или мы всё таки сначала определяемся с таблицей, по которой ищем?
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984522
mayton
Попробуй полазить по немецким сайтам и посмотреть как отдается веб-содержимое. Найдешь хоть один комбо-символ?

https://www.bike-components.de/
прям сразу в верхнем меню
но это utf, а не unicode
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984525
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonStringUTF16.charAt(value, index);

Теперь лезем глубей:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    public static char charAt(byte[] value, int index) {
         checkIndex(index, value);
         return getChar(value, index);
     }

     static char getChar(byte[] val, int index) {
         assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
         index <<= 1;
         return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                       ((val[index]   & 0xff) << LO_BYTE_SHIFT));
     }


Внезапно никаких проверок на композиты, и прочую фигню, тупо пара байт по заданному смещению.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984529
Алексей Роза,

Давайте на примере разберёмся что есть что. Возьмём к примеру GCC 10.2 так как я им пользуюсь в основном.

Возьмём для примера обычное извлечение из массива

Код: plaintext
1.
2.
3.
4.
5.
const static int HashIndex[] = {10, 20, 70, 40, 50};

int GetHashIndex(int i){
  return HashIndex[i];
}



Получаем
Код: sql
1.
2.
  mov eax, DWORD PTR [esp+4]
  mov eax, DWORD PTR HashIndex[0+eax*4]




Теперь испробуем конструкцию switch создав подобную ситуацию
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int GetSwitchHashIndex(int i){
  switch(i)
    {
        case 0: return 10;
        case 1: return 20;
        case 2: return 70;
        case 3: return 40;
        case 4: return 50;
    }
}



Получаем на выходе аналогичный код
Код: sql
1.
2.
  mov eax, DWORD PTR [esp+4]
  mov eax, DWORD PTR CSWTCH.8[0+eax*4]




А теперь имитируем через switch в плане else - if

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int  __attribute__ ((noinline)) CaseCall1(int i, int r) {
    return (i * i) * r;
};
int  __attribute__ ((noinline)) CaseCall2(int i, int r) {
    return r + (i * 10);
};
int  __attribute__ ((noinline)) CaseCall3(int i, int r) {
    return i / (i / 2) * r;
};
int  __attribute__ ((noinline)) CaseCall4(int i, int r) {
    return r / (i / 2);
};



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
int SwitchElseIf(int i, int r){
  switch(i)
    {
        case 0: 
            return CaseCall1(i, r);
        break;
        case 1:
            return CaseCall2(i, r);
        break;
        case 2: 
            return CaseCall3(i, r);
        break;
        case 3: 
            return CaseCall4(i, r);
        break;
    }
}




Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  cmp eax, 2
  je .L7
  jg .L8
  test eax, eax
  jne .L9
  mov DWORD PTR [esp+4], 0
  jmp CaseCall1(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 2
  jmp CaseCall3(int, int)
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 1
  jmp CaseCall2(int, int)
.L8:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 3
  jmp CaseCall4(int, int)
main:
  xor eax, eax
  ret





На выходе получаем страшный и уродливый ASM представляющий из себя else - if конструкцию где если 10000 элементов, то он будет долго перебирать до последнего.

Ты пишешь


Алексей Роза
где именно на программисте лежит ответственность за то, где он что разместит. Невозможность убрать такой неэффективный поиск - это какой-то нонсенс.


Есть возможно контралировать. И вот тут как раз придуман goto array pointer, что бы не иметь миллион else - if

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int SwitchElseIf(int i, int r){
   static const void*Pointers[4] = {&&case0, &&case1, &&case2, &&case3};

goto *Pointers[i];
    case0: 
        return CaseCall1(i, r);
    case1:
        return CaseCall2(i, r);
    case2: 
        return CaseCall3(i, r);
    case3: 
        return CaseCall4(i, r);
}




На выходе мы получаем красивый код Прыжка Адресации
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  jmp [DWORD PTR SwitchElseIf(int, int)::Pointers[0+eax*4]]
.L10:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall4(int, int)
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall3(int, int)
.L8:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall2(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall1(int, int)
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984531
Самая лучшая идея это создание goto array pointer

Теперь вспомним что большинство автоматов к примеру в PHP работает со стандартным switch.


Можно только представить на сколько скорость увеличится, если избавиться от switch конструкции в целом.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984546
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Я придумал хорошую аналогию.
А тут и придумывать ничего не надо: "Я бы взял частями, но мне нужно сразу".

P.S.
Насчёт "не пользуешься - не платишь" - это вы загнули. Платишь.
Необходимостью помнить семантику разных типов конструкторов, способов инициализации и всякой прочей неочевидной чешуи, которая мне, например - никуда не впилась.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984547
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
А что возвращает оператор [] у Ява String?
А нету у класса java.lang.String такого оператора.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984548
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Попробуй полазить по немецким сайтам и посмотреть как отдается веб-содержимое. Найдешь хоть один комбо-символ?
Я, вообще-то, специально цеплял скриншот. Сайт, правда, на русском, но вам же не язык нужен, а факт существования?
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984549
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Внезапно никаких проверок на композиты, и прочую фигню, тупо пара байт по заданному смещению.
Внезапно, но char в java это 16-разрядный код, а не графема полного юникода и уж тем более не глиф.
Именно по этой причине в NIO (java 1.4+) существует CharSequence и "вот это вот всё".
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984556
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov
mayton
Попробуй полазить по немецким сайтам и посмотреть как отдается веб-содержимое. Найдешь хоть один комбо-символ?
Я, вообще-то, специально цеплял скриншот. Сайт, правда, на русском, но вам же не язык нужен, а факт существования?

Я не сомневаюсь что комбо существует.

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

Именно это я хотел сказать Петраву.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984563
Фотография AmKad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
А некоторые советуют размещать ветки в порядке возрастания значений. Это, якобы, позволяет
компилятору генерировать более оптимизированный код...
По идее, если после обработки каждой метки стоит break, то у компилятора есть шанс догадаться отсортировать их в порядке возрастания.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984594
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
SQL2008, кто тебе сказал такую глупость? :)

Существует определенный сложившийся стиль написания кода.
Разумеется никто не запрещает писать "через задницу", а нормальный текст назвать глупостью.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984595
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
SQL2008, кто тебе сказал такую глупость? :)

Давайте вернемся к коду
Итак, какой смысл в данном случае имеет оператор default?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    switch (ch)
    {
    default:
        if ((ptr = strchr(str, ch)) == nullptr)
    case '\0':
    case 'e':
    case 'f':
    case 'g':
            return false;
        else
            count++;
        break;
    }
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984604
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008,

22172656
boobyСтартовый код прост как палка: для набора значений, известных как "хорошие случаи" просто goto на метку return True.
Иначе провести доп проверку (с побочным действием) и решить - true оно return или нет.

Если вы переместите default в конец, то либо увеличите число выходов из функции, ухудшив и читаемость и её размер, либо
если еще захотите структурированного "единственного выхода", добавите переменных для хранения возвращаемого результата.
Код в любом случае ухудшится и для чтения и для компиляции.
А в своем исходном виде он легко читается и компактно компилируется.

2Basil A. Sidorov
в интерфейсе строки в java есть работа с codepoints.
Нормальная в смысле возврата int в качестве значения

Но подозреваю, что там может оказаться подстава.
В том смысле, что у меня нет уверенности, что ява-строки умеют работать с набором кодовых плоскостей в одной строке.
Надо смотреть реализацию.
Если у кого-то есть ссылки на актуальные исходники, например для 8-ки, бросьте пожалуйста ссылку в этот топик.
Глянуть может быть и интересно было бы.
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984608
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008, ассемблер осилишь или транслировать в "ыудусе"? 22170869
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984609
ВсеРазумный
Есть возможно контралировать. И вот тут как раз придуман goto array pointer, что бы не иметь миллион else - if

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int SwitchElseIf(int i, int r){
   static const void*Pointers[4] = {&&case0, &&case1, &&case2, &&case3};

goto *Pointers[i];
    case0: 
        return CaseCall1(i, r);
    case1:
        return CaseCall2(i, r);
    case2: 
        return CaseCall3(i, r);
    case3: 
        return CaseCall4(i, r);
}





На выходе мы получаем красивый код Прыжка Адресации
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  jmp [DWORD PTR SwitchElseIf(int, int)::Pointers[0+eax*4]]
.L10:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall4(int, int)
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall3(int, int)
.L8:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall2(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall1(int, int)


А сравнить с другими вариантами, где case 2 выше всех, например?
Вы таки утверждаете, что в асме всегда будет "по-своему" отсортированный код и там не учтутся предпочтения программиста в упорядочивании поиска?
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984621
Алексей Роза,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int GetSwitchHashIndex(int i){
  switch(i)
    {
        case 1: return 20;
        default:
            return 100;
        case 0: return 10;
        case 2: return 70;
        case 3: return 40;
        case 4: return 50;
    }
}



=>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
GetSwitchHashIndex(int):
  mov edx, DWORD PTR [esp+4]
  mov eax, 100
  cmp edx, 4
  ja .L1
  mov eax, DWORD PTR CSWTCH.2[0+edx*4]
.L1:
  ret




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int GetSwitchHashIndex(int i){
  switch(i)
    {
        case 0: return 10;
        default:
            return 100;
        case 1: return 20;
        case 2: return 70;
        case 3: return 40;
        case 4: return 50;
    }
}



=>

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
GetSwitchHashIndex(int):
  mov edx, DWORD PTR [esp+4]
  mov eax, 100
  cmp edx, 4
  ja .L1
  mov eax, DWORD PTR CSWTCH.2[0+edx*4]
.L1:
  ret




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
int GetSwitchHashIndex(int i){
  switch(i)
    {
        case 0: return 10;
        case 1: return 20;
        case 2: return 70;
        case 3: return 40;
        case 4: return 50;
        default:
            return 100;
    }



=>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
GetSwitchHashIndex(int):
  mov edx, DWORD PTR [esp+4]
  mov eax, 100
  cmp edx, 4
  ja .L1
  mov eax, DWORD PTR CSWTCH.2[0+edx*4]
.L1:
  ret




Код: plaintext
1.
2.
3.
4.
5.
6.
CSWTCH.2:
  .long 10
  .long 20
  .long 70
  .long 40
  .long 50





В таком случае, в котором ты написал default выше... Ему всё равно где он стоит


Тоже самое но с switch - else - if

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int SwitchElseIf(int i, int r){
  switch(i) {    
        case 1:
            return CaseCall2(i, r);
        default:
            return 100;
        case 0: 
            return CaseCall1(i, r);
        case 2: 
            return CaseCall3(i, r);
        case 3: 
            return CaseCall4(i, r);
    }
}



=>

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  cmp eax, 2
  je .L7
  jg .L8
  test eax, eax
  je .L9
  cmp eax, 1
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 1
  jmp CaseCall2(int, int)
.L8:
  cmp eax, 3
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 3
  jmp CaseCall4(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 2
  jmp CaseCall3(int, int)
.L6:
  mov eax, 100
  ret
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 0
  jmp CaseCall1(int, int)




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int SwitchElseIf(int i, int r){
  switch(i) { 
        case 0: 
            return CaseCall1(i, r);
        default:
            return 100;
        case 1:
            return CaseCall2(i, r);
        case 2: 
            return CaseCall3(i, r);
        case 3: 
            return CaseCall4(i, r);
    }
}



=>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  cmp eax, 2
  je .L7
  jg .L8
  test eax, eax
  je .L9
  cmp eax, 1
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 1
  jmp CaseCall2(int, int)
.L8:
  cmp eax, 3
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 3
  jmp CaseCall4(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 2
  jmp CaseCall3(int, int)
.L6:
  mov eax, 100
  ret
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 0
  jmp CaseCall1(int, int)



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int SwitchElseIf(int i, int r){
  switch(i) { 
        case 0: 
            return CaseCall1(i, r);
        case 1:
            return CaseCall2(i, r);
        case 2: 
            return CaseCall3(i, r);
        case 3: 
            return CaseCall4(i, r);
        default:
            return 100;
    }
}



=>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  cmp eax, 2
  je .L7
  jg .L8
  test eax, eax
  je .L9
  cmp eax, 1
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 1
  jmp CaseCall2(int, int)
.L8:
  cmp eax, 3
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 3
  jmp CaseCall4(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 2
  jmp CaseCall3(int, int)
.L6:
  mov eax, 100
  ret
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 0
  jmp CaseCall1(int, int)




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int SwitchElseIf(int i, int r){
  switch(i) { 
        default:
            return 100;
        case 0: 
            return CaseCall1(i, r);
        case 1:
            return CaseCall2(i, r);
        case 2: 
            return CaseCall3(i, r);
        case 3: 
            return CaseCall4(i, r);
    }
}



=>

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  cmp eax, 2
  je .L7
  jg .L8
  test eax, eax
  je .L9
  cmp eax, 1
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 1
  jmp CaseCall2(int, int)
.L8:
  cmp eax, 3
  jne .L6
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 3
  jmp CaseCall4(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 2
  jmp CaseCall3(int, int)
.L6:
  mov eax, 100
  ret
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], 0
  jmp CaseCall1(int, int)






То есть теперь, глядя на это... Можно смело покрутить у виска человеку, который говорит что расположение DEFAULT в коде влияет на что - то.


И вроде ты просил поменять ещё сторонами goto array

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int SwitchElseIf(int i, int r){
   static const void*Pointers[4] = {&&case0, &&case1, &&case2, &&case3};

goto *Pointers[i];
    case2: 
        return CaseCall3(i, r);
    case0: 
        return CaseCall1(i, r);
    case1:
        return CaseCall2(i, r);
    case3: 
        return CaseCall4(i, r);
}



=>
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SwitchElseIf(int, int):
  mov eax, DWORD PTR [esp+4]
  mov edx, DWORD PTR [esp+8]
  jmp [DWORD PTR SwitchElseIf(int, int)::Pointers[0+eax*4]]
.L10:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall4(int, int)
.L9:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall2(int, int)
.L8:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall1(int, int)
.L7:
  mov DWORD PTR [esp+8], edx
  mov DWORD PTR [esp+4], eax
  jmp CaseCall3(int, int)




Сохранил свой порядок
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984623
booby
Если вы переместите default в конец, то либо увеличите число выходов из функции, ухудшив и читаемость и её размер, либо...


rdb_dev
SQL2008, ассемблер осилишь или транслировать в "ыудусе"? 22170869


Компилятор не глупый. Давайте посмотрим что он на деле сделает

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
bool testSwitch()
{
    char ch = 'c'; // Или 'a', например.
    char str[] = "bcd";
    char *ptr = nullptr;
    int count = 0;

    switch (ch)
    {
    default:
        if ((ptr = strchr(str, ch)) == nullptr)
    case '\0':
    case 'e':
    case 'f':
    case 'g':
            return false;
        else
            count++;
        break;
    }

    return true;
}






Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
testSwitch():
  sub esp, 36
  mov DWORD PTR [esp+20], 6579042
  push 99
  lea eax, [esp+24]
  push eax
  call strchr
  test eax, eax
  setne al
  add esp, 44
  ret



Никто не был прав) Потому что код - говнокод без логики
...
Рейтинг: 0 / 0
Очень интересны нюанс с оператором switch
    #39984628
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный

... код - говнокод без логики

зачем же делать глупость , компилируя его?
...
Рейтинг: 0 / 0
25 сообщений из 236, страница 6 из 10
Форумы / C++ [игнор отключен] [закрыт для гостей] / Очень интересны нюанс с оператором switch
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]