LINUX.ORG.RU

История изменений

Исправление r--r--r--, (текущая версия) :

Поставь 32 бита

Теперь ты начинаешь понимать, в чём реальная разница на твоих примерах.

Для 64 бит предполагаю, что компиляторы пользуются фактом, что длина указателя 64-бит, а значит 64-битный номер 4-байтного элемента никак не может переполниться.

Да, но нет. На самом деле компиляторы конечно же не пользуются никакими "фактами".

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

Чтобы включить вставку memset’а надо делать дополнительную логику анализа кода на невозможность переполнения беззнаковых меньше регистра. Этой логики в компиляторах нет. Компиляторы просто в соответствии со стандартом расширяют signed int до int64_t и в случае сравнения между signed int’ом и unsigned int’ом ты получаешь разницу в поведении на разной размерности, а вовсе не какую-то глубокую философию между знаковыми и беззнаковыми, про которые ты тут с упоением рассказываешь. Для unsigned int, который на самом деле uint32_t, компилятор обязан сгенерировать код, допускающий переполнение.

Исправление r--r--r--, :

Поставь 32 бита

Теперь ты начинаешь понимать в чём реальная разница на твоих примерах.

Для 64 бит предполагаю, что компиляторы пользуются фактом, что длина указателя 64-бит, а значит 64-битный номер 4-байтного элемента никак не может переполниться.

Да, но нет. На самом деле компиляторы конечно же не пользуются никакими "фактами".

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

Чтобы включить вставку memset’а надо делать дополнительную логику анализа кода на невозможность переполнения беззнаковых меньше регистра. Этой логики в компиляторах нет. Компиляторы просто в соответствии со стандартом расширяют signed int до int64_t и в случае сравнения между signed int’ом и unsigned int’ом ты получаешь разницу в поведении на разной размерности, а вовсе не какую-то глубокую философию между знаковыми и беззнаковыми, про которые ты тут с упоением рассказываешь. Для unsigned int, который на самом деле uint32_t, компилятор обязан сгенерировать код, допускающий переполнение.

Исходная версия r--r--r--, :

Поставь 32 бита

Теперь ты начинаешь понимать в чём реальная разница на твоих примерах.

Для 64 бит предполагаю, что компиляторы пользуются фактом, что длина указателя 64-бит, а значит 64-битный номер 4-байтного элемента никак не может переполниться.

Да, но нет. На самом деле компиляторы конечно же не пользуются никакими "фактами".

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

Чтобы включить вставку memset’а надо делать дополнительную логику анализа кода на невозможность переполнения беззнаковых меньше регистра. Этой логики в компиляторах нет. Компиляторы просто в соответствии со стандартом расширяют signed int до int64_t и в случае сравнения между signed int’ом и unsigned int’ом ты получаешь разницу в поведении на разной размерности, а вовсе не какую-то глубокую философию между знаковыми и беззнаковыми, про которые ты тут с упоением рассказываешь.