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
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
访问具有“错误”类型的向量时产生的不必要移动操作表。
注意: long
,long long
,unsigned long
,unsigned long long
,size_t
和ptrdiff_t
不需要额外的mov*操作(基本上是任何>=最大对象大小或在64位参考系统上为8字节)
编辑:
我想我可能已经有了一个可行的gcc补丁桩,但我不知道如何在其源代码中完成桩并添加适当的-W标志位,而通常编程中最困难的部分就是命名东西。-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 _____________________________________________
以上代码是指向GCC编译器中c-family/c.opt文件的路径。该文件与C语言及其衍生语言(如C++)相关,可能包含编译器选项。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 __________________________________________
在这个文件中,定义了处理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
的确是不正确的。或者你是想说数组元素大于sizeof(int)
? - Rudy Velthuis