Многие руководства по стилю, такие как 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++.