更换阵列与正确的整型变量的访问 [英] Replacing arrays access variables with the right integer type
问题描述
我已经用INT访问阵列(尤其是在for循环)的习惯;不过,我最近发现,我可能已经做它所有-错,我的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)以{返回v [I] } > movslq%ESI,RSI%
> MOVL(%RDI,%RSI,4),%eax中
> RETINT vector_get(INT * V,为size_t我){返回v [I] } > MOVL(%RDI,%RSI,4),%eax中
> RET
好了,我自己固定的(使用为size_t和ptrdiff_t的现在),现在我怎么(但愿不是手动)找到我的code这些情况,所以我可以解决这些问题?
最近我注意到几个补丁包括 INT
修改为size_t
跨线提锵到来。
我放在一起的那个被插入在每个实例的额外的指令,以显示结果的表做它所有-错。
<大骨节病>
<大骨节病>
<大骨节病>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;焦骨节病>结果
<大骨节病>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;总之骨节病>结果
<大骨节病>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; INT 骨节病>结果
<大骨节病>无符号结果&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;焦骨节病>结果
<大骨节病>无符号结果&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;总之骨节病>结果
<大骨节病>无符号结果&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; INT 骨节病>
骨节病>
<大骨节病>
<大骨节病> movsbq%SIL,RSI%骨节病>结果
<大骨节病> movswq%的硅,RSI%骨节病>结果
<大骨节病> movslq%ESI,RSI%骨节病>结果
<大骨节病>结果movzbl%SIL,ESI%&NBSP; 骨节病>结果
<大骨节病>结果movzwl%的硅%ESI&NBSP; 骨节病>结果
<大骨节病>结果MOVL%ESI,ESI%&NBSP;&NBSP;&NBSP; 骨节病>结果
骨节病>结果
不需要移动操作表结果时,
访问向量与错误的类型。
骨节病>
请注意:长
,长长
,无符号长
,无符号长长
,为size_t
和 ptrdiff_t的
不需要另外MOV *操作(基本上什么> =最大对象的大小,或者64位的参考系统上的8个字节)
编辑:
我想我可能有修补GCC一个可行的存根,但我不知道我身边源的方式来完成存根,并添加适当的-Wflag位,和往常一样编程的最难的部分是命名的东西。 -Wunalinged指数?
<大骨节病>的gcc / C / C-typeck.c _______________________________________________ 骨节病>
如果(!互换)
warn_array_subscript_with_type_char(索引);
&GT;
&GT;如果(sizeof的(指数)LT;的sizeof(为size_t))
&GT; warning_at(LOC,OPT_Wunaligned_index,
&GT; 数组指数比为size_t较小);/ *应用默认促销* *后注意到字符类型。 * /
指数= default_conversion(索引);
<大骨节病>的gcc / C系列/ c.opt _____________________________________________ 骨节病>
三字母组合
çObjC C ++ ObjC ++
-trigraphs支持ISO C三字母
&GT;
&GT; Wunaligned指数
&GT; çObjC C ++ ObjC ++
&GT;警告数组索引比为size_t小民主基金
çObjC C ++ ObjC ++ VAR(flag_undef)
不要predefine系统特异性和GCC的宏
<大骨节病>的gcc / C系列/ C-opts.c __________________________________________ 骨节病>
情况下OPT_Wtrigraphs:
cpp_opts-&GT; warn_trigraphs =价值;
打破;
&GT;
&GT;案例OPT_Wunaligned_index:
&GT; cpp_opts-&GT; warn_unaligned_index =价值;
&GT;案例OPT_Wundef:
cpp_opts-&GT; warn_undef =价值;
打破;
铛和GCC中都有 -Wchar-标
,但这只会帮助检测字符
标类型。
您的可能的考虑修改铛或GCC(较容易建立在你的基础设施),以扩大由 -Wchar-标检测的类型
警告。如果这是一通修复工作,这可能是去了解它的最直接方法。
否则,你就需要找到抱怨的非棉绒 - 为size_t
/ ptrdiff_t的
下标;我不知道任何有这样的选择。
I've had a habit of using int to access arrays (especially in for loops); however I recently discovered that I may have been "doing-it-all-wrong" and my x86 system kept hiding the truth from me. It turns out that int is fine when sizeof(size_t) == sizeof(int)
but when used on a system where sizeof(size_t) > sizeof(int)
, it causes an additional mov
instruction. size_t and ptrdiff_t seem to be the optimal way on the systems I've tested, requiring no additional mov
.
Here is a shortened example
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
OK, I've fixed myself (using size_t and ptrdiff_t now), now how do I (hopefully not manually) find these instances in my code so I can fix them?
Recently I've noticed several patches including changes from int
to size_t
coming across the wire mentioning Clang.
I put together a table of the extra instructions that get inserted on each instance to show the results of "doing-it-all-wrong".
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.
Note: long
, long long
, unsigned long
, unsigned long long
, size_t
and ptrdiff_t
require no additional mov* operation (basically anything >= largest object size, or 8 bytes on the 64 bit reference system )
Edit:
I think I may have a workable stub for patching gcc, but I don't know my way around its source to complete the stub and add proper -Wflag bits, and as usual the hardest part of programming is naming stuff. -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 and gcc have -Wchar-subscripts
, but that'll only help detect char
subscript types.
You might consider modifying clang or gcc (whichever is easier to build on your infrastructure) to broaden the types detected by the -Wchar-subscripts
warning. If this is a one-pass fix effort, this might be the most straightforward way to go about it.
Otherwise you'll need to find a linter that complains about non-size_t
/ptrdiff_t
subscripting; I'm not aware of any that have that option.
这篇关于更换阵列与正确的整型变量的访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!