Здравствуйте, vopl, Вы писали:
V>Да, согласен . На один бит. Но не "гораздо меньше".
Так в 2 раза же.
V>>>Он "более уместен" потому что не имеет знака, который на самом деле не нужен. Из за этого, например, мой компилятор не генерирует дополнительную проверку на отрицательность в том цикле.
N>>А с чего бы это быть той проверке? Есть масса других вариантов обойти.
V>Ну хз. Тут видно, один лишний test https://gcc.godbolt.org/z/HZBYFv
А, на входе... я тело цикла смотрел, там идентично. Что там на входе делается — обычно, считается, на производительность не влияет — посмотрите какой ужас компилируется при векторизации на входе и выходе основного цикла — и всё равно это считается безвредным
Но тут проблема не типа как такового — к моменту прихода оптимизаций типы уже стёрты, а диапазона значений. Проверка выбрасывается в правом случае потому, что после конверсии end-beg в беззнаковое оказывается, что в условии немедленного выхода "0 >= (unsigned size_t)(end-beg)" случай "больше" невозможен и его можно не проверять. Но это корректно только до тех пор, пока реально end >= beg! Вы косвенно, за счёт неявной конверсии к беззнаковому в этом сравнении, гарантируете это условие (и получите очень больно, если нарушите его).
В нормальном современном языке можно было бы это условие записать явно, как часть предусловий на вызов функции, и тогда 1) проверка была бы выброшена и со знаковой переменной цикла, 2) компилятор получил бы шанс проверить вызовы функции на корректность.