加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用正确的整数类型替换数组访问变量

发布时间:2020-12-16 07:09:18 所属栏目:百科 来源:网络整理
导读:我有习惯使用int来访问数组(特别是在for循环中);但是我最近发现我可能一直在“做错了”而且我的x86系统一直向我隐瞒真相.事实证明,当sizeof(size_t)== sizeof(int)时int是正常的,但是当在sizeof(size_t)的系统上使用时sizeof(int),它会导致一个额外的mov指令
我有习惯使用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,%eax
    > ret

好的,我已经修好了自己(现在使用size_t和ptrdiff_t),现在我如何(希望不是手动)在我的代码中找到这些实例,以便我可以修复它们?

最近我注意到了几个补丁,包括从int到size_t的变化,提到了Clang.

我整理了一个表格,其中列出了在每个实例上插入的额外指令,以显示“do-it-all-wrong”的结果.

??
????烧焦
????短
????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,但我不知道我的方法来完成存根并添加正确的-Wflag位,并且像往常一样,编程中最难的部分是命名东西. -Wunalinged指数?

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;我不知道有任何选择.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读