我有使用 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。
我将插入每个实例的额外指令放在一起,以显示“全错”的结果。
<知识库>
<知识库>
字符
短
整数
无符号
字符
无符号
短
无符号
int
<知识库>
movsbq %sil, %rsi
movswq %si, %rsi
movslq %esi, %rsi
movzbl %sil, %esi
movzwl %si, %esi
movl %esi, %esi
不需要的移动操作表
访问具有“错误”类型的 vector 。
注意:long
, long long
, unsigned long
, unsigned long long
, size_t
和 ptrdiff_t
不需要额外的 mov* 操作(基本上任何 >= 最大对象大小,或 64 位引用系统上的 8 字节)
编辑:
我想我可能有一个可用的 stub 来修补 gcc,但我不知道如何绕过它的源代码来完成 stub 并添加适当的 -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;
最佳答案
clang 和 gcc 有 -Wchar-subscripts
,但这只会帮助检测 char
下标类型。
您可能考虑修改 clang 或 gcc(以更容易在您的基础架构上构建为准)以扩大 -Wchar-subscripts
警告检测到的类型。如果这是一次性修复工作,这可能是最直接的解决方法。
否则,您将需要找到一个提示非size_t
/ptrdiff_t
下标的 linter;我不知道有哪个选项。
关于c - 用正确的整数类型替换数组访问变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24864103/