У меня была привычка использовать int для доступа к массивам (особенно для циклов); однако недавно я обнаружил, что я, возможно, "делаю-все-неправильно", и моя система x86 скрывала от меня правду. Оказывается, int отлично, когда sizeof(size_t) == sizeof(int)
, но при использовании в системе, где sizeof(size_t) > sizeof(int)
, он вызывает дополнительную инструкцию mov
. size_t и ptrdiff_t кажутся оптимальными для систем, которые я тестировал, не требуя дополнительных mov
.
Вот укороченный пример
int vector_get(int *v,int i){ return v[i]; }
> movslq %esi, %rsi
> movl (%rdi,%rsi,4), %eax
> ret
int vector_get(int *v,size_t i){ return v[i]; }
> movl (%rdi,%rsi,4), %eax
> ret
ОК, я исправил себя (используя size_t и ptrdiff_t сейчас), теперь как я (надеюсь, не вручную) нахожу эти экземпляры в своем коде, чтобы я мог их исправить?
Недавно я заметил несколько патчей, включая изменения от int
до size_t
, проходящие через провод, в котором упоминается Clang.
Я собрал таблицу дополнительных инструкций, которые вставлены в каждый экземпляр, чтобы показать результаты "делать-все-неправильно".
char
short
int
unsigned
char
unsigned
short
unsigned
int
movsbq %sil, %rsi
movswq %si, %rsi
movslq %esi, %rsi
movzbl %sil, %esi
movzwl %si, %esi
movl %esi, %esi
Table of unwanted move operations when
accessing vectors with "wrong" type.
Примечание: long
, long long
, unsigned long
, unsigned long long
, size_t
и ptrdiff_t
не требуют дополнительной операции mov * (в основном ничего >= наибольший размер объекта или 8 байтов на 64-битной эталонная система)
Edit:
Я думаю, что у меня может быть работоспособный заглушка для исправления gcc, но я не знаю своего пути по его источнику, чтобы заполнить заглушку и добавить соответствующие бит -Wflag, и, как обычно, самая сложная часть программирования - это именование. -Wunalinged-индекс?
gcc/c/c-typeck.c _______________________________________________
if (!swapped)
warn_array_subscript_with_type_char (index);
>
> if ( sizeof(index) < sizeof(size_t) )
> warning_at (loc, OPT_Wunaligned_index,
> "array index is smaller than size_t");
/* Apply default promotions *after* noticing character types. */
index = default_conversion (index);
gcc/c-family/c.opt _____________________________________________
trigraphs
C ObjC C++ ObjC++
-trigraphs Support ISO C trigraphs
>
> Wunaligned-index
> C ObjC C++ ObjC++
> Warn about array indices smaller than size_t
undef
C ObjC C++ ObjC++ Var(flag_undef)
Do not predefine system-specific and GCC-specific macros
gcc/c-family/c-opts.c __________________________________________
case OPT_Wtrigraphs:
cpp_opts->warn_trigraphs = value;
break;
>
> case OPT_Wunaligned_index:
> cpp_opts->warn_unaligned_index = value;
>
case OPT_Wundef:
cpp_opts->warn_undef = value;
break;