更换阵列与正确的整型变量的访问 [英] Replacing arrays access variables with the right integer type

查看:200
本文介绍了更换阵列与正确的整型变量的访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆