使用最小的必要 C 类型与仅使用 int

Using smallest necessary C type vs just using int

给定一个 C 函数(随机示例):

void* getMyStuff( size_t size, unsigned char alignment );

使用 unsigned char 是通过告诉编译器传递的值的限制来帮助编译器,还是通过阻止编译器使用本机 int(或 unsigned int) 大小?

我知道过去使用 short 并不理想,因为 16 位操作不是本机的。我不知道这是否适用于此处(或一般的局部变量)。

基本上,如果您要传递小于 32 位的值,这可能适合较小的数据类型,编译器会关心您选择哪个吗?

作为参考,我正在使用 GCC 和 Clang,编译 C11(不是 C++11)代码。这个问题可能是 ABI 特定的,但我不知道如何确定。

编辑:如果重要的话,我正在 x86_64 上开发。我希望答案不会因 CPU 个供应商而异。

Does using unsigned char help the compiler by telling it the limit of the values being passed, or does it hinder the compiler by preventing it from using the native int (or unsigned int) size?

取决于 CPU 和 ABI。最有效的方法完全取决于 ABI 记录为最快的调用约定。

一般来说,高端 CPU 喜欢使用他们喜欢的数据宽度和对齐类型。 32 位对应 32 位 CPUs 等等。然而,它们可能支持对较小类型的操作。低端 CPUs(8 或 16 位)根本不喜欢较大的类型,如果可能,通常更喜欢使用 8 位类型。

I know historically it's not ideal to use short since 16-bit operations were not native.

不是本地人在哪里? 16 位操作在所有 16 位 CPU 上都是完美的“本机”。对于 16 位数据的指令支持较差的 32 bits,它们可能并不理想。

Basically, if you are passing values smaller than 32-bit, that could fit in a smaller data type, does the compiler care which you choose?

编译器通常不允许将您选择的类型换成更大的类型,因为这可能会改变程序的含义和行为。 uint_fast8_t 和类似的现代类型除外,如果它导致更快的代码,编译器可以换成更大的类型。

For reference, I'm using GCC and Clang

编译器无关紧要。只有特定的目标端口及其 ABI 很重要。尽管在某些低端 CPU 上,如专用微控制器,通常没有标准化的 ABI,因此每个编译器都为该目标发明了自己的 ABI/calling 约定。

正如@WeatherVane 在评论中所说,简单的答案是:

使用 int 除非有充分的理由不这样做。

我不会用一堆痛苦的重复论点来延长这个答案:一切都已经说过很多次了。如果您使用 charshort 作为参数类型,通常不会出错,但实际上,也没有任何好处。你可能会花更多的时间担心它,而不是用任何其他方式弥补。

正如安德鲁在评论中提醒我的那样,intunsigned int 之间的选择很重要;我并不是要建议忽略这种区别。