о переносимости софта |
[Aug. 18th, 2013|01:21 am] |
libbitap совершенно непортабельна. то есть, совсем. сейчас поясню. вот так вот автор проверяет перенос при сдвиге:
int value; carry = ((value<<1) < 0); это же ужас-ужас-ужас. в стандарте операции с переполнением дают неопределённый результат, и обязательность представления целых чисел в виде two's complement никак не указана.
вообще, си на самом деле очень хуёво подходит на роль «переносимого макроассемблера». например, практически у всех процессоров есть carry flag. очень полезная штука. было бы логично иметь в си стандартные операции хотя бы для проверки оного — ан хер. формат целых чисел тоже не указан. результат арифметики с переполнением — не указан. ни «заэнфорсить», ни проверить фичи целевой системы стандартным образом тоже нельзя. то, что авторы компиляторов ленивые и перекладывают «неопределённые» результаты прямиком на процессор — всего лишь частности реализации.
блядь, да стандартизуйте вы уже всё это! большинство процессоров работают именно так. но нет: «а вдруг когда-то все будут использовать другие?» да похуй, всё равно куча кода при этом сломается, потому что люди тупо пишут в рассчёте на теперешние реалии. ну, как ломался код, когда шестьдесят четыре бита только-только входили в моду. и если про приведение поинтеров к интам ещё кое-как можно ворнинг показать, то про арифметику с переменными — хуй, потому что хуй знает, какие там у переменных значения будут.
и да: стандарт с «неопределённым поведением» — говно. всё «неопределённое поведение» надо или определить, или объявить фатальной ошибкой. некоторые ошибки снабдить оговоркой: «соответствующий стандарту компилятор обязан определять ошибочные ситуации на этапе компиляции, когда это позволяет его — компилятора — архитектура. соответствующий стандарту компилятор обязан генерировать код, определяющий ошибочные на этапе исполнения.» да, оговорка хуёвая, но в общем случае невозможно определить, например, валидна ли операция с неизвестными операндами в момент компиляции программы. и никто не мешает добавить в компилятор флаг «идите нахуй с вашими стандартами и проверками, я знаю, что делаю.» кто это использует — тот сам себе дурак. |
|
|
Comments: |
бля, сю забыл полностью... мне казалось что в сях так нельзя вопче - int value; это разве можно так? кресты какиято)
![[User Picture]](http://lj.rossia.org/userpic/197531/22349) | From: | ketmar |
Date: | August 18th, 2013 - 12:39 am |
---|
| | | (Link) |
|
(удивлённо) а как целое-то объявляют? «боже великий всемогущий, да славится имя твоё, ниспошли свою благодать на эту переменную и да будет она во веки веков содержать целые числа, аминь!»?
помню типа только так: int i = 0; хотя это как раз кресты и есть, то есть у КР было так: int i; i=0; и после этого - никаких больше деклараций))
![[User Picture]](http://lj.rossia.org/userpic/197531/22349) | From: | ketmar |
Date: | August 18th, 2013 - 12:54 am |
---|
| | | (Link) |
|
вообще-то насколько я помню, у k&r как раз объявления с инициализацией появились очень быстро. а вот объявления переменных в начале любого блока, а не только главного блока функции -- этого не было, вроде бы.
ну и да: очевидно же, что у меня перед проверкой переноса опущена куча кода: какой смысл неинициализированную переменную-то проверять? объявление я для иллюстрации типа поставил.
![[User Picture]](http://lj.rossia.org/userpic/197531/22349) | From: | ketmar |
Date: | August 18th, 2013 - 12:55 am |
---|
| | | (Link) |
|
в смысле, в первых версиях компилятора, емнип, как раз надо было сначала явно объявить, а потом уже значение присваивать. | |