【发布时间】:2014-09-11 21:35:33
【问题描述】:
我有使用 int 访问数组的习惯(尤其是在 for 循环中);然而,我最近发现我可能一直在“做错事”,而我的 x86 系统一直对我隐瞒真相。事实证明,当 sizeof(size_t) == sizeof(int) 时 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
短
int
无符号
char
无符号
短
无符号
int
movsbq %sil, %rsi
movswq %si, %rsi
movslq %esi, %rsi
movzbl %sil, %esi
movzwl %si, %esi
movl %esi, %esi kbd>
当
时不需要的移动操作表
访问具有“错误”类型的向量。
注意:long、long long、unsigned long、unsigned long long、size_t 和 ptrdiff_t 不需要额外的 mov* 操作(基本上任何 >= 最大对象大小,或 64 位上的 8 个字节参考系统)
编辑:
我想我可能有一个可用于修补 gcc 的存根,但我不知道如何绕过它的源来完成存根并添加适当的 -Wflag 位,并且像往常一样,编程中最难的部分是命名。 -Wunalinged-index?
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;
【问题讨论】:
-
您是否使用
int作为索引,或者您的意思是什么?如果数组大于MAXINT,则int确实是错误的。或者你的意思是数组elements大于sizeof(int)? -
换句话说,你能给出一个你认为错误访问的代码示例吗?
-
数组的大小根本不重要,只是系统的能力拥有超过 MAXINT 个元素。我会澄清的。
-
与其乱用 MAXINT,我想你可以直接说
sizeof(size_t) > sizeof(int)。 -
@ecatmur - 简洁,我喜欢。固定的。还添加了几个示例。
标签: c arrays int static-analysis compiler-optimization