Re[10]: У всех свои цели :)
От: Erop Россия  
Дата: 24.11.06 09:51
Оценка:
Здравствуйте, johny5, Вы писали:

J> А тут не верно. int32_t он на то и 32 что на всех платформах 32х битный целочисленный и переносимость будет 100%.

J> Конечно если на 16 битной машине нет 32х битных чисел вообще, то реализовать такой тип — придётся потрудиться. Главная цель — портируемость.

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



J>Моё ИМХО: выбор signed/unsigned типа — решение проектировщика — это, я понимаю, высокий (абстрактный) уровень. Тут не учитываются детали имплементации а только декларируется соглашение API о принимаемых/возвращаемых значениях. В данном случае вы предоставляете "барьер", человек, предоставляющий unsigned значение должен удостовериться что он предоставляет его правильно, соответственно API может быть спокойна за знаковость значения и наоборот.

Вот если бы ещё правила С++ это всё позволяли...
Ещё раз спрошу: "от чего бы такие ограничения не наложть прямо
Автор: Erop
Дата: 17.11.06
?" Зачем химичить с модульной арифметикой?


J>А неумение программиста работать с unsigned типом и вообще пренебрежение низкоуровневыми деталями, которые предоставляет язык — это уже совсем другая проблема и лечиться она повышением квалификации програмиста, повышением уровня warning-ов + концепция warning -> error, административными методами. В крайнем случае, можно сменить язык на более высокоуровневый, например на ваш FORTRAN.

обычно смотрят в сторону нет или явы
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[23]: встречный ликбез.
От: dr.Chaos Россия Украшения HandMade
Дата: 14.12.06 10:43
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Erlond, Вы писали:


E>>Бывают, я же не говорил, что их не бывает. Я привёл конкретный пример с типами int и unsigned int. И задал по нему вполне конкретный вопрос.

E>>Здесь идёт разговор о целых знаковых и целых беззнаковых числах, числа с плавающей запятой выходят за рамки этой дискуссии, т.к. они не являются целыми и т.к. они всегда знаковые

E>Собственно для тех участников обсуждения, ктьо не знает всех подрбностей.

E>Весь сыр-бор происходит от того, что аппаратура вольна представлять знаковые целые числа как ей заблагорассудится.
E>И стандарт С++ не навязывает ей двоичного-дополнительного кода.
E>Так что бывают реализации С++, в которых int реализован как бит занака и unsigned мантиса. Увы.

Нет сыр бор был в том что опасно использовать unsigned . Андрей сказал, что не опасно и просто требует большей внимательности. Если ты пишешь под какую-то конкретную платформу, то не знать ее особенности просто преступление .
Если пишется изначально переносимый код, то написать обертку не так сложно, а вещи зависимые от конкретной платформы будут в одном месте, что станет вполне управляемо.

Если у нас будут большие числа и серьезные вычисления над ними, тут надо брать большую разрядность или опять же писать свою обертку.

По поводу хранения величин по смыслу unsigned в signed, это правда толком ничего не дает, хотя я думаю это стоит отнести к вопросам стиля. А все вопросы связанные со стилем это уже СВ .

Но полагаю, что при использовании unsigned все таки нет UB, т.к. он одинаково представляется на всех платформах. Да и он правда заставляет быть более внимательным.

Можно провести аналогию с исключениями, т.к. они требуют значительно больше внимания чем коды возврата, но и дают тоже больше гарантий.
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[6]: мои измышления про unsigned, size_t и стандарт
От: dr.Chaos Россия Украшения HandMade
Дата: 14.12.06 11:19
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, night beast, Вы писали:


NB>>По поводу Страуструпа. Если бы все было так однозначно, то vector::size_type был бы интом.


E>Собственно я подумал и понял почему ни size_t, ни размер std::vector, ни его индекс не могут быть в С/С++ знаковым типом.

E>Это всё происходит из-за так называемой совместимости.

E>Действительно, никто не запрещает в C++ иметь очень большие объекты. Напимер объект размером почти со всю адресуемую память. Или vector.

E>Мало того, такие реализации наверняка были, когда компьютеры были слабее ZX Spectrum. Не пресоналки, а реальные такие компьютеры. Большие-пребольшие.

E>Так что если мы хотим сформулировать стандарт языка, который будет описывать и такие архитектуры, мы просто не можем выбрать другой тип, кроме unsigned


Дело не только в диапазоне, но и в отсутствии UB. Т.е. правильно написанная итерация будет работать правильно на всех платформах.

Ты причину верно указал, только пример не очень привел .

E>В некотором смысле это просто следствие того, как было принято делать компьютеры. Только и всего.

А как их было принято делать?
E>

E>Теперь предлагаю посмотреть на это дело с другой стороны.
E>В конце концов переносимость C++ программ -- это миф.
E>Попробуйте написать сложную программу, которая легко переживёт перенос на платформу сильно другой разрядности. Скажем из 32-бит в 16?

Если изначально был такой переход задуман, то довольно легко. Если нет, то это будет очень кроваво.
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[24]: Ещё раз о галвном :)
От: Erop Россия  
Дата: 14.12.06 12:10
Оценка:
Здравствуйте, dr.Chaos, Вы писали:

DC>По поводу хранения величин по смыслу unsigned в signed, это правда толком ничего не дает, хотя я думаю это стоит отнести к вопросам стиля. А все вопросы связанные со стилем это уже СВ .

DC>Но полагаю, что при использовании unsigned все таки нет UB, т.к. он одинаково представляется на всех платформах. Да и он правда заставляет быть более внимательным.

Ну собственно мой взгляд такой. Пока ван не нужны операции сдвига, деления и взятия остатка с участием отрицательных чисел, то вам signed ничем не мешает, а unsigned не даёт никаких преимуществ.

При этом у signed для хранения именно чисел остаётся то приимущество, что труднее переполнить по вычитанию. Ну и вообще assert'ы писать проще, циклы вские.
Всё-таки цикл for устроен так, что для того чтобы он кончился, его параметр должен принять невалидное значение

А если вам таки нужны опасные операции с отрицательными целыми числами (/ % << >>), то вам unsigned тут точно не помошник
Помошник тут приведение к положительным, вычисление, а потом соответсвующая смена знака.
Вывод: числа всегда лучше хранить в signed числах, но можно приделать обёртку (если это действительно нужно), которая правильно вычисялет подобные операции.

Вот у нас, например, есть функции round, ceil и floor, которые делят, округляя в нужную сторону. Правда нет округлялки к 0. Но это потому, что она "так и не приг-Г-Г-годилась"

DC>Можно провести аналогию с исключениями, т.к. они требуют значительно больше внимания чем коды возврата, но и дают тоже больше гарантий.


Ну вот, ИМХО, эта анология ложная, так как unsigned не то что дают какие-то гарантии, а наоборот, в тех случаях, когда у signed возможны проблемы, гарантирует проблемы в любом случае, при преобразованиях между signed и unsigned арифметикой
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[25]: Ещё раз о галвном :)
От: dr.Chaos Россия Украшения HandMade
Дата: 14.12.06 12:20
Оценка: 6 (1)
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, dr.Chaos, Вы писали:


DC>>По поводу хранения величин по смыслу unsigned в signed, это правда толком ничего не дает, хотя я думаю это стоит отнести к вопросам стиля. А все вопросы связанные со стилем это уже СВ .

DC>>Но полагаю, что при использовании unsigned все таки нет UB, т.к. он одинаково представляется на всех платформах. Да и он правда заставляет быть более внимательным.

E>Ну собственно мой взгляд такой. Пока ван не нужны операции сдвига, деления и взятия остатка с участием отрицательных чисел, то вам signed ничем не мешает, а unsigned не даёт никаких преимуществ.


Да я понял твой взгляд, я все обсуждение прочел.

DC>>Можно провести аналогию с исключениями, т.к. они требуют значительно больше внимания чем коды возврата, но и дают тоже больше гарантий.


E>Ну вот, ИМХО, эта анология ложная, так как unsigned не то что дают какие-то гарантии, а наоборот, в тех случаях, когда у signed возможны проблемы, гарантирует проблемы в любом случае, при преобразованиях между signed и unsigned арифметикой


Я согласен что преимуществ значительно меньше, но они таки есть. Для хранения в беззнаковом их действительно почти нет, но для индексов и размеров массивов, это разумно.

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

Использование беззнаковых делает человека более внимательным, а это уже плюс.
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[7]: мои измышления про unsigned, size_t и стандарт
От: Erop Россия  
Дата: 14.12.06 15:09
Оценка:
Здравствуйте, dr.Chaos, Вы писали:

DC>Дело не только в диапазоне, но и в отсутствии UB. Т.е. правильно написанная итерация будет работать правильно на всех платформах.

Странно. Объясни мне, где UB, например, в таком вот коде:
double sum = 0.0;
for( int i = array.size() - 1; i >= 0; i -= step ) {
    sum += array[i];
}


Казалось бы UB случается, когда мы переходим signed<->unsigned на значениях, не помещающихся в оба типа и ещё есть зависимость от реализации при некоторых (не самых нужных обычно) операциях над отрицательными числами.
При сложении/вычитании без переполнения никакого UB нет!

E>>В некотором смысле это просто следствие того, как было принято делать компьютеры. Только и всего.

DC>А как их было принято делать?
Ну были компы, у которых памяти было мало и можно было родить объект на всю почти память, например.
E>>

E>>Попробуйте написать сложную программу, которая легко переживёт перенос на платформу сильно другой разрядности. Скажем из 32-бит в 16?

DC>Если изначально был такой переход задуман, то довольно легко. Если нет, то это будет очень кроваво.

Ну если изначально писать под несколько платформ, то почти любой язык в каком-то смысле переносим
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[26]: Ещё раз о галвном :)
От: Erop Россия  
Дата: 14.12.06 15:21
Оценка:
Здравствуйте, dr.Chaos, Вы писали:

DC>Портируемость С++ ты видимо не верно понимаешь . Она говорит о том что стандартная библиотека будет работать на разных платформах одинаково, а то что ты написал, это уж извини как написал так и работает .


Ну я понимаю просто. Вот написал я прогу для Win, а кастомеры говорят: "Хотим и под Mac OS!"
Вопрос: "сколько будет стоить перенос"
Короче в практическо-управленческом ключе

DC>Использование беззнаковых делает человека более внимательным, а это уже плюс.

Ну в принципе так можно поступать всегда, тогда будешь аскетом.
Например можно ездить не на удобной иномарке а на очень старой "копейке". Тоже не будет давать слишком сильно лихачить
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: offtopic
От: Ulfur Россия  
Дата: 14.12.06 15:54
Оценка:
Здравствуйте, Erop, Вы писали:

E> [...]


Читал Ваши рассуждения о переносе программ на другие платформы... У меня был опыт переноса части программы с 32-х битной платформы на 16-и битную, причем довольно широко использовались вычисления с целыми числами. Если Вам или кому-то еще будет интересно — прошу посмотреть
Автор: Ulfur
Дата: 31.10.06
— то, что я уже пытался безуспешно обсудить со здешними форумчанами
В конечном счете именно С++ (на С мой подход по естественным причинам не повторить) позволил избежать ряда грубых ошибок и падений — ценой производительности, но только в отладочной сборке.

Если нужно будет оградить себя любой ценой от переполнений, то опять же проблему можно решить средствами С++ (естественно, что в ущерб производительности и памяти), описав класс работающий с числами независимо от их разрядности (типа BigNum и иже с ним). При грамотном подходе можно реализовать это с довольно небольшими требованиями к памяти и высоким быстродействием (Эх, жаль что на это времени не осталось ).
Re[27]: Ещё раз о галвном :)
От: dr.Chaos Россия Украшения HandMade
Дата: 14.12.06 16:14
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, dr.Chaos, Вы писали:


DC>>Портируемость С++ ты видимо не верно понимаешь . Она говорит о том что стандартная библиотека будет работать на разных платформах одинаково, а то что ты написал, это уж извини как написал так и работает .


E>Ну я понимаю просто. Вот написал я прогу для Win, а кастомеры говорят: "Хотим и под Mac OS!"

E>Вопрос: "сколько будет стоить перенос"
E>Короче в практическо-управленческом ключе
Это в сторону JVM и CLR.

DC>>Использование беззнаковых делает человека более внимательным, а это уже плюс.

E>Ну в принципе так можно поступать всегда, тогда будешь аскетом.
E>Например можно ездить не на удобной иномарке а на очень старой "копейке". Тоже не будет давать слишком сильно лихачить

Ну лихачь, лихачь .
Побеждающий других — силен,
Побеждающий себя — Могущественен.
Лао Цзы
Re[11]: У всех свои цели :)
От: johny5 Новая Зеландия
Дата: 15.12.06 08:58
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, johny5, Вы писали:


J>> Конечно если на 16 битной машине нет 32х битных чисел вообще, то реализовать такой тип — придётся потрудиться. Главная цель — портируемость.


E>А вот если чтобы работала и при этом хорошо (без тормозов, перерасхода ресурсов, органично для целевой платформы и надежно), то все эти ужимки тебе не помогут


Ну в общем ужимки портирования никак не связаны с основным топиком, тут хоть int хоть unsigned, всё равно придётся думать.
При заведомо непродуманном для портирования коде замены unsigned -> int это как случайно поворачивая собирать кубик-рубик в надежде что всё заработает.


E>

J>>Моё ИМХО: выбор signed/unsigned типа — решение проектировщика — это, я понимаю, высокий (абстрактный) уровень. Тут не учитываются детали имплементации а только декларируется соглашение API о принимаемых/возвращаемых значениях. В данном случае вы предоставляете "барьер", человек, предоставляющий unsigned значение должен удостовериться что он предоставляет его правильно, соответственно API может быть спокойна за знаковость значения и наоборот.

E>Вот если бы ещё правила С++ это всё позволяли...

А почему они не позволяют этого? Декларируете что то как unsigned — всё, больше ничего не надо. А поиск ошибок переполнения, ошибок со знаками это задача программиста и компилятора.

E>Ещё раз спрошу: "от чего бы такие ограничения не наложть прямо
Автор: Erop
Дата: 17.11.06
?" Зачем химичить с модульной арифметикой?


Вы там предлагаете вариант int_for_unsigned, что примерно означает: "тут вообще то должен быть unsigned, но т.к. у нас программисты совсем тупые, то мы сделаем int чтобы уменьшить количество ошибок хотя бы с антипереполнением".

Используя только тип int вы понижаете декларативное свойство интерфейсов. Кроме как в комментарии к коду у вас не будет возможности сказать, что значение всегда должно быть положительным. В вашем примере:

int get_buratino_apples(Buratino& )


неочевидно, что функция не может вернуть например -1 как сигнал ошибки, и пользователь будет вынужден явно позаботиться, написав проверку (assert или if). Если он не позаботиться сразу, то позднее, имплементор функции get_buratino_apples может догадаться, что не для всяких буратин функция может вернуть правильное значение и тогда пользователи этой функции "огребут по полной".

прототип функции

unsigned get_buratino_apples(Buratino& )


гарантирует положительность ответа, и если все возвращаемые значения потенциально возможны (т.е. у вас нет способа через возвращаемое значение заявить об ошибке), то проверка на валидность объекта класса Buratino будет уже стоять внутри функции get_buratino_apples.
Re[12]: Беззнаковые иллюзии
От: Пётр Седов Россия  
Дата: 15.12.06 16:33
Оценка: +1
Здравствуйте, johny5, Вы писали:

J>Используя только тип int вы понижаете декларативное свойство интерфейсов. Кроме как в комментарии к коду у вас не будет возможности сказать, что значение всегда должно быть положительным. В вашем примере:


J>
J>int get_buratino_apples(Buratino& )
J>


J>неочевидно, что функция не может вернуть например -1 как сигнал ошибки, и пользователь будет вынужден явно позаботиться, написав проверку (assert или if). Если он не позаботиться сразу, то позднее, имплементор функции get_buratino_apples может догадаться, что не для всяких буратин функция может вернуть правильное значение и тогда пользователи этой функции "огребут по полной".


J>прототип функции


J>
J>unsigned get_buratino_apples(Buratino& )
J>


J>гарантирует положительность ответа,

Здесь тоже непонятно, возвращает ли функция специальное значение. Функция может вернуть std::string::npos (функция std::string::find) или TLS_OUT_OF_INDEXES (функция TlsAlloc).

J>и если все возвращаемые значения потенциально возможны (т.е. у вас нет способа через возвращаемое значение заявить об ошибке),

А как это узнать из прототипа функции? Всё равно придётся читать комментарии или документацию. В обоих случаях (int и unsigned) прототип функции ничего не говорит про специальное возвращаемое значение.

J>то проверка на валидность объекта класса Buratino будет уже стоять внутри функции get_buratino_apples.
Пётр Седов (ушёл с RSDN)
Re[13]: Беззнаковые иллюзии
От: johny5 Новая Зеландия
Дата: 16.12.06 03:22
Оценка: +1
Хорошо, но вы согласны, что unsigned даёт просто больше декларативной информации чем int (целое и положительное vs целое)?
Re[12]: Пример кода с "преимуществами"
От: Erop Россия  
Дата: 16.12.06 09:41
Оценка:
Здравствуйте, johny5, Вы писали:

J>Ну в общем ужимки портирования никак не связаны с основным топиком, тут хоть int хоть unsigned, всё равно придётся думать.

J>При заведомо непродуманном для портирования коде замены unsigned -> int это как случайно поворачивая собирать кубик-рубик в надежде что всё заработает.
+1. Я про то же. signed/unsigned мало помогает в реальной портируемости кода. Да и вообще в C++ сильно не самый портируемый язык, ИМХО.
E>>

E>>Вот если бы ещё правила С++ это всё позволяли...
J>А почему они не позволяют этого? Декларируете что то как unsigned — всё, больше ничего не надо. А поиск ошибок переполнения, ошибок со знаками это задача программиста и компилятора.
Ну, например, потому, что так устроены правила выбора результата целочисленной операции.
Смотри, пусть i -- это int si -- signed int, а ui -- это unsigned int (так же и s, ss и us).
Каковы, по товоему, типы (и результаты) следующих результатов вычислений?
    unsigned int ui = 2;
    int i = 2;
    signed int si = -2;

    signed short ss = -2;
    short s = 2;
    unsigned short us = 2;
    
    ui - ui;    // это мне "нравится". 
    ui + ui;
    ui * si;    // это мне "нравится". 
        us + us;
    ui * ss;    // сопоставление этого и следующего мне тоже очень "нравится"
    us * ss;  
    ui % ss;    // тоже весьма "логично"  :shuffle:
Ну и так далее...

Вот скажем тебе надо закодировать какую-то формулу, скажем такую простую:
max( xxxQuality / 2 + yyyUnsignedQuality * yyyCoef, zzzQuality + zzzQualityShift );
Вот если, скажем тут yyyUnsignedQuality не может быть отричательным чисорм и по этому оно unsigned, то результат этого выражения начинает сильно очень зависеть от типов всех параметров
Ну вот и на хрена ерундой заниматься? Может лучше отлаживать таки саму формулу, а не особенности её кодироания с использованием unsigned типов?


J>Вы там предлагаете вариант int_for_unsigned, что примерно означает: "тут вообще то должен быть unsigned, но т.к. у нас программисты совсем тупые, то мы сделаем int чтобы уменьшить количество ошибок хотя бы с антипереполнением".
Не, это обозначает, ровно то, что написано: "Челое число, которое, если не отходить очень далеко от 0, ведёт себя как число, которому запрещено принимать отрицательные значения). При чём тут вообще арифметика по модулю 2 в какой-то степени (AKA тип unsigned int)?

J>Используя только тип int вы понижаете декларативное свойство интерфейсов. Кроме как в комментарии к коду у вас не будет возможности сказать, что значение всегда должно быть положительным. В вашем примере:


J>
J>int get_buratino_apples(Buratino& )
J>


J>неочевидно, что функция не может вернуть например -1 как сигнал ошибки, и пользователь будет вынужден явно позаботиться, написав проверку (assert или if). Если он не позаботиться сразу, то позднее, имплементор функции get_buratino_apples может догадаться, что не для всяких буратин функция может вернуть правильное значение и тогда пользователи этой функции "огребут по полной".


Как интересно! А что же будет, если функция будет возвращать unsigned, а "имплементор функции get_buratino_apples может догадаться, что не для всяких буратин функция может вернуть правильное значение"?
Если будут возвращать UINT_MAX, а вызывающая сторона не ухом ни рылом, то конечно будет намного лучше.
Ещё можешь обдумать такую вот тему. Предтавь, что результат как-то так используют, что существенно закладываются на неотрицательность. Скажем аллокирут массив, под хранение свойств каждого из яблок. Если тип, возвращают signed, то случится что?
Если напишут assert, то он провалится и мы сразу всё отладим, а если, например, нет assert, то случится какая-то хитрая ошибка в new, и тоде будут таки шансы всё отладить.
А вот если какой-то урод, стёр в интрефесе комментарий, поменял семантику метода, не поменяв его имени, и начал таки возвращать вместо числа яблок число UINT_MAX, то принимающий код скорее всего не будет содержать никакого вменяемого assert'а. Кроме того, new просто и незамысловато сможет ответить "не хватает памяти".

Ну вот и у тебя прекрасная ситуация. Работает твоя прога. В каком-то редком случае на большом запросе случается нехватка памяти. Твои действия?
(Альтернатива -- assert => сразу ясно что случилось)

J>прототип функции

J>
J>unsigned get_buratino_apples(Buratino& )
J>


J>гарантирует положительность ответа, и если все возвращаемые значения потенциально возможны (т.е. у вас нет способа через возвращаемое значение заявить об ошибке), то проверка на валидность объекта класса Buratino будет уже стоять внутри функции get_buratino_apples.


А вот и фигушки! Тот "мегаразработчик", который начнёт неожиданно из функции "число яблок", в комментарии которой написано, что типа результат -- 0 или больше, возвращать значение "-5" может и тип результата поменять вообще-то.

А что мешает так же делать и с signed ответом?
Опять же, что мешает, (если реально возникают такие проблемы), использовать int_for_unsigned
Автор: Erop
Дата: 17.11.06
?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: Беззнаковые иллюзии
От: Erop Россия  
Дата: 16.12.06 09:47
Оценка:
Здравствуйте, johny5, Вы писали:


J>Хорошо, но вы согласны, что unsigned даёт просто больше декларативной информации чем int (целое и положительное vs целое)?

Я согласен, что слово unsignrd, написанное перд функцией можно договориться считать обозначающим именно это -- 2функция возвращает вообще-то числа, но неотрицательные", но это намного дороже, чем договориться писать про это в комментариях.
Почему? -- Да потому, что слово unsigned говорит языку C++ много такого, чего лучше бы не говорить

Могу привести пример (я его, кажется уже приводил, но не нашёл где)
Можно, примерно так же, договориться, что слово register маркирует переменные, которые связаны с регистрацией чего-нибудь в госрганах, а слово auto -- омееющие отношение к автомобилям.
В принципе можно, но есть две проблемы
1) Во всех других случаях мы так не делаем. То есть про автомобили, чётные числа, ограниченность результата сверху мы пишем в комментариях или в названиях идентифекаторов, а не при помощи подходящих по звучанию ключевых слов C++
2) Эти все ключевые слова как-то меняют код. Далеко не всегда удачно.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: Беззнаковые иллюзии
От: Пётр Седов Россия  
Дата: 18.12.06 16:28
Оценка: 9 (1)
Здравствуйте, johny5, Вы писали:
J>Хорошо, но вы согласны, что unsigned даёт просто больше декларативной информации чем int (целое и положительное vs целое)?
Да. Но, во-первых, эта декларативность не подкрепляется run-time-проверками (в широко используемых компиляторах).
Во-вторых, арифметика с unsigned int беззнаковая. В простых случаях (например, итерация массива в прямом порядке) беззнаковая арифметика не вызывает проблем. Но когда появляется беззнаковое вычитание, риск ошибиться возрастает (так как беззнаковая арифметика отличается от обычной в районе нуля). Беззнаковая арифметика — низкоуровневая техника. Она позволяет выжать из компьютера максимум (дополнительный бит), но за это приходится платить. Код с беззнаковой арифметикой хрупкий, подвержен ошибкам. От программиста требуется повышенное внимание/напряжение, иначе любое изменение кода может незаметно внести ошибку (которая проявляется только в граничном случае; например, когда vec.size() = 0). А вот код со знаковой арифметикой часто не содержит ошибок просто потому, что вычисляется именно то, что имел в виду программист. Так что беззнаковую арифметику лучше избегать. А если уж использовать (в исключительных случаях), то изолировать в классе или функции.
Для обработки целых чисел вместо unsigned int лучше использовать int + assert. Во-первых, assert гораздо более выразителен, чем модификатор 'unsigned' (по которому не скажешь, является ли ноль допустимым значением). Например:
void SetWeights(int Count, double Weight)
{
  assert(Count > 0);
  assert(Weight > 0.);
  ...
}

Такие ограничения не выразить с помощью модификатора 'unsigned' (тем более что типа 'unsigned double' просто нет).
Во-вторых, в отличие от модификатора 'unsigned', assert делает run-time-проверку (в Debug-конфигурации) и сигналит (MessageBox, abort, DebugBreak, исключение, ...), если условие не выполняется. То есть не будет такого, что -1 молчаливо преобразуется в 4 294 967 295 и цикл выполняется четыре миллиарда раз.
Кстати, assert может сообщать полезную информацию не только программисту, но и компилятору. Например, в MSVC6 assert можно определить так:
#ifdef _DEBUG
  ...
#else // Release-конфигурация
  #define assert(Cond) __assume(Cond)
#endif

Это позволяет генерировать такой же оптимальный ассемблерный код, как и для unsigned int. Например, если есть переменная n типа int и код содержит 'assert(n >= 0)', то компилятор имеет право (в Release-конфигурации) транслировать выражение 'n / 8' в одну инструкцию битового сдвига (на 3 бита вправо, так как 8 = pow(2, 3)).
Пётр Седов (ушёл с RSDN)
Re[4]: Нужен ли unsigned
От: Programador  
Дата: 11.04.07 11:51
Оценка:
Здравствуйте, Андрей Тарасевич,

Вы писали:

АТ>Результат знакового целочисленного переполнения — UB. Беззнаковые типы реализуют арифметику по модулю, т.е. у них не бывает "переполнения" или, другими словами, традиционное переполнение у них приводит к однозначно оговоренному эффекту без какого-либо UB.


ТОлько этот модуль не оговорен В документе исо 14882-1998 — 3ю9ю1ю4 (не могу закопипастить) сказано про particular size of integer. С предыдущим пунктом это можно трактовать как 2^31 причем сомнительно можно ли particular трактовать как модуль 2^32 Помоему совпадение это не particular Другими словами может ли диапазон быть больше самого большого знакового Ну или не UB, но во всех компиляторах не так
Re[21]: Давай немного подробнее?
От: CreatorCray  
Дата: 16.04.07 00:32
Оценка:
Здравствуйте, Erop, Вы писали:

E>>1. Не вижу смысла использоваться знаковые целые для величин, которые не будут отрицательными -> дополнительная информация тому, кто будет использовать код

E>Это вообще не выгода Выгода, это когда ты что-то получаешь.
E>Видимо то, что слово unsigned в С++ обозначает нечто очень своеобразное и совсем другое (модульная арифметика, тоо сё) тебе не важно.
Ну, не знаю чем вам так не угодили беззнаковые типы. Мне как начинавшему с ассемблера что int что unsigned int — один фиг. Только в умножении/делении разница. И беззнаковое для меня применительно к значениям, которые не могут стать отрицательными гораздо логичнее чем гипотетическая выгода в вылете в отрицательную область значений при каком либо выверте кода. Я не могу вспомнить когда последний раз сталкивался с подобной проблемой.

E>>2. Т.к. нет отрицательных значений убирается проверка на то, что значение выскочило "ниже" положенного. То, что удобно ловить ошибки по отрицательным — не соглашусь, ошибку нужно ловить перед выполнением операции.

E>А в чём смысл? Идея в том, что так эффективнее или в чём-то ещё?
Разумеется эффективнее

E>>3. Если в коде с беззнаковой арифметикой содержится ошибка, то она очень быстро даст о себе знать, в отличие от знаковой, на которой до поры, до времени всё будет работать, а когда ошибка даст о себе знать, то тогда уже может понадобиться ни день, и не два на отладку. Вполне возможно, что всё будет работать до самого релиза.

Абсолютно согласен.

E>Просто во втором проще ошибиться

Ну пардон, принцип "сперва подумай — потом сделай" никто не отменял.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[23]: Давай немного подробнее?
От: CreatorCray  
Дата: 16.04.07 00:32
Оценка:
Здравствуйте, Erop, Вы писали:

E>1) Твой код не эквивалентен моему

E>У меня массив итерируется с конца в начало! А вдруг мне надо именно так?
E>Вот при знаковом i всё равно куда и с каким шагом итерировать, а вот с unsigned начинаются косяки и двери
Не вопрос:

unsigned int i = count;
while (i--)
   do_somthing (i);


Коротко и просто. Будет работать как для int так и для uint. В чем проблема то? Что то мне все больше кажется что в личной неприязни к unsigned.
"Как? Ви не любите кошекЪ??? Та ви просто не умеете их готовить!!!" (С)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Всё очень просто....
От: CreatorCray  
Дата: 16.04.07 00:32
Оценка:
Здравствуйте, <Аноним>, Вы писали:

Ш>>Например, напиши struct IPHeader без беззнаковых типов. Или сделай алгоритм вычисления CRC (а так же SHA, DES, длинная арифметика и.т.п.).

А>То есть ты прибавляешь один IP к другому, а порты отнимаешь друг от друга и две получившиеся величины перемножаешь между собой?

Сам то понял что сказал?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Нужен ли unsigned
От: CreatorCray  
Дата: 16.04.07 00:32
Оценка:
Здравствуйте, Шахтер, Вы писали:

R>>Я думаю таких примеров можно найти ещё.

Ш>Примеров откровенного ламерства, когда люди простейший цикл не могут написать, действительно можно найти вагон и прицепную тележку.
+100!

Ш>Точно так же нет вещественных, и всё что мы имеем -- это жалкий float.

Ну и чуть чуть менее жалкий double
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.