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

标签 c arrays int static-analysis compiler-optimization

我有使用 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),现在我该如何(希望不是手动)在我的代码中找到这些实例以便修复它们?

最近我注意到几个补丁,包括从 intsize_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_tptrdiff_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/

相关文章:

通过 macOS 终端编译, fatal error : stdio. h: No such file or directory

c++ - 指向 int 的指针。 C++

javascript - 映射来自 Twitch API 的评论 - React

python - PySpark - 从 Numpy 矩阵创建 DataFrame

ios - 为什么我的 Dictionary Item 总是返回 0? swift

c - 如何在字符串中集成 int 变量?

c - 为什么会出现段错误(核心已转储)?

c - 结果不是来自正确的分支

c - 插入排序不打印 C 中的所有值

在 C 中复制无符号 int 数组