Многие руководства по стилю, такие как Google, рекомендуют использовать int
как целое число по умолчанию при индексировании массивов, например. С ростом 64-битных платформ, где большую часть времени int
составляет всего 32 бита, что не является естественной шириной платформы. Как следствие, я не вижу причин, кроме простого, сохранить этот выбор. Мы ясно видим, что при компиляции следующего кода:
double get(const double* p, int k) {
return p[k];
}
который компилируется в
movslq %esi, %rsi
vmovsd (%rdi,%rsi,8), %xmm0
ret
где первая команда поддерживает 32-битное целое число в целое число 64 бит.
Если код преобразуется в
double get(const double* p, std::ptrdiff_t k) {
return p[k];
}
сгенерированная сборка теперь
vmovsd (%rdi,%rsi,8), %xmm0
ret
что ясно показывает, что CPU чувствует себя как дома с std::ptrdiff_t
чем с int
. Многие пользователи C++ перешли в std::size_t
, но я не хочу использовать целые числа без знака, если мне действительно не нужно поведение по модулю 2^n
.
В большинстве случаев использование int
не ухудшает производительность, так как неопределенное поведение или недочетное целочисленное переполнение позволяют компилятору внутренне продвигать любой int
в std::ptrdiff_t
в циклах, которые имеют дело с индексами, но мы ясно видим из вышеизложенного, что компилятор делает не чувствовать себя как дома с int
. Кроме того, использование std::ptrdiff_t
на 64-битной платформе сделает переполнение менее вероятным, поскольку я вижу, что все больше и больше людей попадают в ловушку от переполнения int
когда им приходится иметь дело с целыми числами больше 2^31 - 1
которые становятся действительно распространенными Эти дни.
Из того, что я видел, единственное, что делает int
стороне, похоже, состоит в том, что литералы, такие как 5
являются int
, но я не вижу, где это может вызвать любую проблему, если мы перейдем к std::ptrdiff_t
как значение по умолчанию целое число.
Я нахожусь на грани создания std::ptrdiff_t
как стандартного целого числа de facto для всего кода, написанного в моей небольшой компании. Есть ли причина, почему это может быть плохой выбор?
PS: Я согласен с тем, что имя std::ptrdiff_t
является уродливым, и именно поэтому я наложил его на il::int_t
который выглядит немного лучше.
PS: Насколько я знаю, многие люди рекомендуют мне использовать std::size_t
как целое по умолчанию, я действительно хочу дать понять, что я не хочу использовать целое число без знака как мое целое число по умолчанию. Использование std::size_t
как целого по умолчанию в STL было ошибкой, признанной Бьярне Страуступом и стандартным комитетом в интерактивной панели видео : спросите нас все, что угодно, в момент времени 42:38 и 1:02:50.
PS: Что касается производительности, то на любой 64-битной платформе, которую я знаю, +
, -
и *
компилируется одинаково для int
и std::ptrdiff_t
. Таким образом, нет никакой разницы в скорости. Если вы разделите константу времени компиляции, скорость будет одинаковой. Это только когда вы делите a/b
когда ничего не знаете о b
что использование 32-битного целого числа на 64-битной платформе дает вам небольшое преимущество в производительности. Но этот случай настолько редок, что я не вижу в качестве выбора переход от std::ptrdiff_t
. Когда мы имеем дело с векторизованным кодом, здесь есть явная разница, и чем меньше, тем лучше, но это другая история, и не было бы оснований придерживаться int
. В таких случаях я бы рекомендовал использовать типы фиксированного размера C++.