LINUX.ORG.RU

В Си предложили добавить switch-case для строк

 , ,


0

3

Привет, чат!

Спустя много лет, в язык Си наконец предложено добавить возможность использовать выражение switch-case для строк. Например, можно будет писать вот такое:

const char *s = get_some_string();

switch(s) {
case "this":
  handle_this();
  break;
case "that":
  handle_that();
  break;
default:
  handle_other();
  break;
}

Таким образом, в Си будет чуть меньше способов отстрелить себе ноги.

Ссылка на предложение: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3895.pdf



Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от yorshka

GCC появился до Linux

Это ты себе отвечай. Это же ты перевёл разговор с GCC на Linux.

И нам это известно откуда?

Оттуда, что ещё до 15-ого года были проекты по развёртыванию инсталляций на коммерческих unix. Это не считая слона в комнате.

r--r--r--
()
Ответ на: комментарий от yorshka

те страдали. А те и рады!

Вот именно, а вы, раз не хотите это принять, ошиблись дверью :)

mky ★★★★★
()
Ответ на: комментарий от mky

Вобще из обсуждений на форумах никто не может сказать, почему с самого начала, на PDP-11, когда NULL обозначался как ((char*)0) было выбрано именно значение 0x0000, хотя, вроде как, там лежит вектор какого-то прерывания. При том, что, ЕМНИП, памяти конкретно на той PDP-11 было не по максимуму, то есть был «пустые» адреса.

По моему это очевидно. И не только для PDP-11. В процессоре есть команды только для сравнения с нулем. Для сравнения с любым другим значением мы теряем 2 байта и время.

Да и по поводу NULL какие проблемы? Достаточно допущения, что выделенная память не будет нулевым указателем. Да и strchr например не найдет символ по нулевому адресу, если в качестве аргумента мы даем ей указатель на какой-то свой буфер. А указатель на таблицу прерываний может быть и нулевым. Какая разница нулевой указатель или нет, если мы не собираемся его освобождать или использовать в качестве отрицательного ответа результата функции?

uart
()
Ответ на: комментарий от yorshka

main – это часть системного API. Она будет вызвана с вполне определённым данным форматом данных на входе. Другого пути тут нет. Если не нравится, правь компилятор.

Вовсе нет. Функция будет вызвана с теми аргументами, с какими захочется тому, кто ее вызывает. Или не вызвана вообще. К системному API отношения не имеет, да и к компилятору тоже. Компилятор выдал объектный файл, c чем ты его линковать будешь не его забота.

uart
()
Ответ на: комментарий от r--r--r--

Это ты себе отвечай. Это же ты перевёл разговор с GCC на Linux.

Не переводил. Linux тут – просто пример открытой экосистемы. Под BSD тоже ничего не было, раз уже тебе угодно.

Оттуда, что ещё до 15-ого года были проекты по развёртыванию инсталляций на коммерческих unix.

Конечно были, бабло ж надо пилить-то как-то. Те же менеджеры сбербанка поимели просто неприличные откаты от IBM на внедрении AIX.

Это не считая слона в комнате.

Какого? Не томи же нас!

yorshka
() автор топика
Ответ на: комментарий от yorshka

Какие же вы одинаковые. :) Одни и те же паттерны, по кругу. Придумали про меня какие-то «переполняющиеся буфера» и тиражируете в своей уютной секте рукожопов по простой причине - у вас в методичках «переполняющиеся буфера» есть, а на то, что в чём было дело в реальности у вас просто мозгов не хватает. Поэтому тупо заменяете реальную непонятку вызубренным «переполнением буфера» из вашей методички и тиражируете, опять же, согласно методичке.

Забавно, что в том споре мне никто так и не привёл реального примера в реальном контексте, когда read сразу после успешного open может вернуть ошибку, и при этом лютом звездеце в системе реально будут иметь существенное значение какие-то там возможные дальнейшие проблемы в некритичной софтине.

Как дело доходит до реальности, жопорукие жители манямирка внезапно сливаются. Всегда и без исключений.

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

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

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 1)
Ответ на: комментарий от uart

какие проблемы

Несоответствие стандарту и UB. Про -fno-delete-null-pointer-checks уже написано, встретив if (ptr) сам компилятор не знает, что это — проверка на NULL или проверка на zero.

Достаточно допущения, что выделенная память

Ну дак пусть так в стандарте, и напишут, если это всех устраивает. А то стандарт развязывает руки писателям компиляторов, что ((void*)0) не обязан быть 0x000000. Отсюда лезут всякие советы, что если вам нужно обращаться к адресу 0x000000, то пишите asm-вставки, тогда типа всё хорошо, по NULL-указателю тогда не будет объектов Си, не будет UB, так как ассемблер не Си. Только это бредовый совет. А в ядре уже заложили, что NULL не может быть fullptr (0xFFFFFF), придумав «IS_ERR_OR_NULL».

Стандарт рисует красивую абстракцию, что: int i=0; ((void*)i) — это типа не NULL-ptr, но по факту они не различимы.

указатель на таблицу прерываний может быть и нулевым

В случае МК, особенно гарвардской архитектуры, на 0x000000 может быть не вектор прерывайний, а вполне себе код или данные.

И не только для PDP-11. В процессоре есть команды только для сравнения с нулем.

Процессоров было много разных.

мы теряем 2 байта

Откуда два байта взялось? Ограниченный взгляд. INC (инкремент) вполне может кодироваться одним байтом, а загрузка значения в регистр не везде выставляла флаги, могло быть, что флаг ноль выставлялся только после операции с содержимым регистра. Если null будет 0xFFFFFFF, то INC проверямый указатель и смотри флаг нуля.

В целом, размер указателя не int, поэтому сколько машинных операций занимает сравнение с нулём заранее не известно. А можно ещё добавить, что есть (были) машины, у которых можно читать только слово (18-64 бит) и там разименовывание char-указателя занимает много операций, и на этом фоне экономия на проверке, что указатель не NULL малозначима. Они ведь на PDP-11 перешли с PDP-7, где 36-бит было.

mky ★★★★★
()
Ответ на: комментарий от mky

Ну ещё можно добавить, касательно того, что NULL - это такой же адрес как и все остальные. Для Си, может и как остальные, но голый Си без libc, как бы и не Си. А вот что выведет:

printf("The value of ptr is %p", NULL);
0x0000000, (nil), (nullptr) или вобще неведомо что? Замечательно, если засовываем в код отладочную печать, а потом парсим скриптами выхлоп.

mky ★★★★★
()
Ответ на: комментарий от mky

Откуда два байта взялось? Ограниченный взгляд. INC (инкремент) вполне может кодироваться одним байтом, а загрузка значения в регистр не везде выставляла флаги, могло быть, что флаг ноль выставлялся только после операции с содержимым регистра. Если null будет 0xFFFFFFF, то INC проверямый указатель и смотри флаг нуля.

Вот лежит указатель в локальной переменной ptr, по адресу R6+смещение, Проверить на 0 можно одной командой TST, а сравнить с константой CMP + 2 байта (указатель WORD). Если надо с этим ptr что-то делать, то просто загружаем его в R0 например и уже имеем сравнение с 0, не надо делать лишнее сравнение или портить регистр с с помощью INC.

Процессоров было много разных.

Но в целом сравнение с нулем у процессором скорее правило, чем исключение. Не могу ничего сказать про PDP-7, не знаю, да и отвечал я про PDP-11.

Несоответствие стандарту и UB

Какому стандарту это не соответствует и в чем? И незачем бояться UB. Это лишь говорит об отсутствии гарантии на всех архитектурах и компиляторах. Ну и что? Вот пишу я прикладную программу под Linux, Windows, Mac. Никто мне не даст реальный указатель на 0x0000000000000000. А пишу модуль ядра, загрузчик, программу для ДОС или ДВК, так там может быть и адрес 0 вполне реальный и нужный адрес.

А то стандарт развязывает руки писателям компиляторов, что ((void*)0) не обязан быть 0x000000.

Конечно не обязательно, это может быть например DS:0x0000.

uart
()
Ответ на: комментарий от yorshka

Чтобы проверить на 0 регистр на x86 можно сделать:

test eax, eax
jz error

Проверка на -1 и другие значения будет длиннее (например, придётся использовать cmp, который несёт в опкоде константу и его опкод длиннее, либо трюки с inc + test, которые добавляют инструкцию, плюс потом нужно восстанавливать исходное значение, если оно нам таки нужно).

Да, процессорных архитектур много, но практически везде есть быстрое сравнение с нулём (без необходимости этот самый ноль явно кодировать в опкоде как константу). А с -1 нет.

С учётом того, что проверка на NULL очень популярная операция, то её оптимальное кодирование важно.

Да, по 0 адресу может что-то лежать. Но, во-первых, на первых компьютерах не было защиты памяти и программа продолжит работу и при чтении/записи по адресу -1 где памяти нет. Плюс небольшая адресная арифметика (тот же +1 для доступа ко второму байту word) и вот мы опять залезли в нулевой адрес. Защита переоценена. А, во-вторых, пользовательские структуры по 0 адресу не лежат, этого достаточно. Адрес таблицы прерываний не будет хранится/передаваться в структуры, где NULL имеет значение, он будет использоваться в редких системных функциях (например, смена обработчика прерывания), которые знают, что проверять на NULL адрес не нужно.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 5)
Ответ на: комментарий от KivApple

Проверка на -1 и другие значения будет длиннее

Да и насрать? Я не представляю себе код, в котором узким местом будет проверка валидности указателя.

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

На PDP-11, под который писали этот ваш Евнухс на этой вашей сишечке, защита памяти таки была.

А, во-вторых, пользовательские структуры по 0 адресу не лежат, этого достаточно.

Пользовательские структуры и по адресу FFFF….FFFF не лежат.

yorshka
() автор топика
Ответ на: комментарий от yorshka

Да, процессорных архитектур много, но практически везде есть быстрое сравнение с нулём (без необходимости этот самый ноль явно кодировать в опкоде как константу). А с -1 нет.

Алсо да, напомню, что на куче архитектур нулевой указатель имел битовое представление, отличное от 0x0000...0000 (к счастью, почти все эти архитектуры давно сдохли). Это вообще весьма шизофреничная фишка, я знаю, но битовое представление нулевого указателя не обязано быть нулевым.

yorshka
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.