Что: 66e846326ec104c644c977d7be848d4e4fe0b729 Когда: 2024-10-22 11:01:35+03:00 ------------------------------------------------------------------------ Темы: c ------------------------------------------------------------------------ Снова про решения при разработке на Си В прошлых проектах я всегда для всех структур и enum-ов делал typedef-ы. Мне казалось, что без них как-то не очень отображаются человекочитаемые имена в LLDB. Но то ли времена поменялись, то ли я чего напутал, но сейчас проблем нигде не заметил. И стал указывать просто "struct XXX" и "enum XXX". В 5f1645eb510d76ffb07c07fa09bffdea01959c03 и 81768895c53201dd862f7164ded5c7a90de6c55b как-то заходила речь про тип переменных для указания индексов в массивах и размерах данных. С одной стороны много говорят про то, что с знаковым типом сильно проще, ибо при переполнении он станет отрицательным. С беззнаковым будет использоваться арифметика с модулями. И я склонялся к этому варианту и решению, использованию каких-нибудь ptrdiff_t. Однако, переполнение signed числа является undefined behaviour! Тогда как переполнение unsigned чётко и понятно определено. На практике, так как у нас 2's complement, поведение *скорее всего* будет определено, но компилятор из-за UB может и проблем подкинуть из-за оптимизации которую он решил проделать. Есть -fwrapv (3f2f2ebd3ca7c13eaa4f4bdb0043032d0daeac03) опция, которая позволяет форсировать строгое поведение при переполнении signed, но оно закрывает путь к некоторым возможным оптимизациям (судя по тому что пишут). Во многих случаях, что с signed, что с unsigned -- надо проверять не произошло ли переполнение. Это в любом случае if-ы. Так что у меня выбор свёлся либо к: использовать -fwrapv, либо без него. Без него означает меньше требований к флагам компиляции и это даёт возможность использовать на один бит больше. Так что для размеров я уже точно без сомнений считаю, что в Си нужен size_t, не забывая про проверки переполнения. В ЯПах без UB для signed переполнений, типа Go, использовать signed тип, если не критично что один бит теряется. Собственно, Go и использует int для len() и индексов массивов. ------------------------------------------------------------------------ оставить комментарий: mailto:comment@blog.stargrave.org?subject=Re:%20%D0%A1%D0%BD%D0%BE%D0%B2%D0%B0%20%D0%BF%D1%80%D0%BE%20%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%BF%D1%80%D0%B8%20%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B5%20%D0%BD%D0%B0%20%D0%A1%D0%B8%20%2866e846326ec104c644c977d7be848d4e4fe0b729%29 ------------------------------------------------------------------------ комментарий 0: From: David Rabkin Date: 2024-10-26 12:35:23Z В Си99 typedef-ы нужны для алиасов, чтобы не писать struct в типах переменных, вот тут подробно: https://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions Может, что поменялось в стандарте за четверть века? Опять же, в Си99 size_t рекомендован для размеров и индексов. Зачем он иначе нужен? А дискуссия про типы индекса интересная, да. ------------------------------------------------------------------------ комментарий 1: From: Sergey Matveev Date: 2024-10-26 20:35:49Z *** David Rabkin [2024-10-26 15:32]: >В Си99 typedef-ы нужны для алиасов [...] Это то понятно. Я прежде так и делал. Но тут вот убедился, что не так уж и сложно писать "struct" рядом со структурами. Оно не напрягает. >Опять же, в Си99 size_t рекомендован для размеров и индексов. Зачем он >иначе нужен? А дискуссия про типы индекса интересная, да. Рекомендован или стандартизован -- не значит что это обязательно адекватно и продуманно. В Си есть и wchar_t, что точно не стоит использовать. ------------------------------------------------------------------------ Сгенерирован: SGBlog 0.34.0