为什么C提供的整数类型对于任何项目都不够好? [英] Why aren't the C-supplied integer types good enough for basically any project?
问题描述
我更像是一个系统管理员而不是一个程序员。但是我花了大量的时间在程序员的代码中徘徊,试图弄清楚出了什么问题。当程序员期望__u_ll_int32_t的一个定义或者其他什么(是的,我知道那不是真的)时,会有一些令人不安的 时间用于处理问题,但要么预期定义该类型的文件在某处除了它之外,或者(这是更糟糕的,但幸运的是,很少见)预期该定义的语义不是它的。
I'm much more of a sysadmin than a programmer. But I do spend an inordinate amount of time grovelling through programmers' code trying to figure out what went wrong. And a disturbing amount of that time is spent dealing with problems when the programmer expected one definition of __u_ll_int32_t or whatever (yes, I know that's not real), but either expected the file defining that type to be somewhere other than it is, or (and this is far worse but thankfully rare) expected the semantics of that definition to be something other than it is.
据我了解C,它故意不对整数类型进行宽度定义(并且这是一件好事),而是给程序员 char
, short
, int
, long
, long long
,在他们所有的签名和未签名的荣耀中,具有定义的最小值,实现(希望)满足。此外,它为程序员提供了各种宏,实现必须提供这些宏来告诉你诸如char的宽度,最大的unsigned long等等。然而,任何非平凡的C项目似乎要做的第一件事就是导入或发明另一组类型,它们明确地给出了8位,16位,32位和64位整数。这意味着作为系统管理员,我必须将这些定义文件放在程序员期望的地方(毕竟,我的工作),但不是所有这些定义的所有语义都是相同的(这个轮已经多次重新发明)并且我不知道在这里满足所有用户需求的非临时方式。 (我有时会使用< bits / types_for_ralph.h>,我知道每次我都会让小狗哭。)
As I understand C, it deliberately doesn't make width definitions for integer types (and that this is a Good Thing), but instead gives the programmer char
, short
, int
, long
, and long long
, in all their signed and unsigned glory, with defined minima which the implementation (hopefully) meets. Furthermore, it gives the programmer various macros that the implementation must provide to tell you things like the width of a char, the largest unsigned long, etc. And yet the first thing any non-trivial C project seems to do is either import or invent another set of types that give them explicitly 8, 16, 32, and 64 bit integers. This means that as the sysadmin, I have to have those definition files in a place the programmer expects (that is, after all, my job), but then not all of the semantics of all those definitions are the same (this wheel has been re-invented many times) and there's no non-ad-hoc way that I know of to satisfy all of my users' needs here. (I've resorted at times to making a <bits/types_for_ralph.h>, which I know makes puppies cry every time I do it.)
尝试什么明确地定义数字的位宽(用一种特别不想做的语言)获得程序员,这使得所有这些配置管理头疼吗?为什么不知道定义的最小值和平台提供的MAX / MIN宏足以完成C程序员想要做的事情?你为什么要选择一种语言,它的主要优点是它可以在任意比特的平台上移植,然后自己输入特定的比特宽度?
What does trying to define the bit-width of numbers explicitly (in a language that specifically doesn't want to do that) gain the programmer that makes it worth all this configuration management headache? Why isn't knowing the defined minima and the platform-provided MAX/MIN macros enough to do what C programmers want to do? Why would you want to take a language whose main virtue is that it's portable across arbitrarily-bitted platforms and then typedef yourself into specific bit widths?
推荐答案
当C或C ++程序员(以下简称第二人称)选择整数变量的大小时,通常会出现以下情况之一:
When a C or C++ programmer (hereinafter addressed in second-person) is choosing the size of an integer variable, it's usually in one of the following circumstances:
- 根据它所代表的真实世界值,您知道(至少粗略地说)变量的有效范围。例如,航空公司预订系统中的
-
numPassengersOnPlane
应该包含最大的支持飞机,因此需要至少10位。 (最多16个。) -
numPeopleInState
在美国人口普查制表程序中需要容纳人口最多的州(目前大约有3800万),所以至少需要26位。 (最多可达32个。)
- You know (at least roughly) the valid range for the variable, based on the real-world value it represents. For example,
numPassengersOnPlane
in an airline reservation system should accommodate the largest supported airplane, so needs at least 10 bits. (Round up to 16.)numPeopleInState
in a US Census tabulating program needs to accommodate the most populous state (currently about 38 million), so needs at least 26 bits. (Round up to 32.)
在这种情况下,您需要语义来自
< stdint.h>
的int_leastN_t
。程序员在这里使用精确宽度intN_t
是很常见的,技术上他们不应该这样做;然而,8/16/32/64位机器今天占据绝对优势,这种区别仅仅是学术性的。In this case, you want the semantics of
int_leastN_t
from<stdint.h>
. It's common for programmers to use the exact-widthintN_t
here, when technically they shouldn't; however, 8/16/32/64-bit machines are so overwhelmingly dominant today that the distinction is merely academic.你可以使用标准类型并依赖于诸如
int
之类的约束必须至少为16位,但缺点是没有标准的最大大小对于整数类型。如果int
恰好是32位,当你真的只需要16位时,那么你的数据大小就会不必要地增加一倍。在许多情况下(见下文),这不是问题,但如果你有一个百万数字的数组,那么你将会遇到很多页面错误。You could use the standard types and rely on constraints like “
int
must be at least 16 bits”, but a drawback of this is that there's no standard maximum size for the integer types. Ifint
happens to be 32 bits when you only really needed 16, then you've unnecessarily doubled the size of your data. In many cases (see below), this isn't a problem, but if you have an array of millions of numbers, then you'll get lots of page faults.- 您的数字不需要那么大,但出于效率原因,您需要一个快速的本地数字。数据类型而不是可能需要浪费在位掩码或零/符号扩展上的小数据类型。
这是
int_fastN_t
中的类型< stdint.h>
。但是,在这里使用内置的int
是很常见的,在16/32位的日子里语义为int_fast16_t
。它不是64位系统上的本机类型,但它通常足够好。This is the
int_fastN_t
types in<stdint.h>
. However, it's common to just use the built-inint
here, which in the 16/32-bit days had the semantics ofint_fast16_t
. It's not the native type on 64-bit systems, but it's usually good enough.- 变量是一个内存量,数组索引,或者转换指针,因此需要一个取决于可寻址内存量的大小。
这对应于typedef
size_t
,ptrdiff_t
,intptr_t
等。你有在这里使用typedef,因为 no 内置类型保证是内存大小。This corresponds to the typedefs
size_t
,ptrdiff_t
,intptr_t
, etc. You have to use typedefs here because there is no built-in type that's guaranteed to be memory-sized.- 该变量是使用
fread
/fwrite
序列化到文件的结构的一部分,或者从非调用C语言(Java,COBOL等),它有自己的固定宽度数据类型。
- The variable is part of a structure that's serialized to a file using
fread
/fwrite
, or called from a non-C language (Java, COBOL, etc.) that has its own fixed-width data types.
在这些情况下,你真的做到了需要精确宽度类型。
In these cases, you truly do need an exact-width type.
- 您还没有考虑过合适的类型,并使用
int
出于习惯。
- You just haven't thought about the appropriate type, and use
int
out of habit.
通常,这是有效的l够了。
Often, this works well enough.
总之,来自
< stdint.h>的所有typedef ;
有他们的用例。但是,内置类型的有用性受限于:So, in summary, all of the typedefs from
<stdint.h>
have their use cases. However, the usefulness of the built-in types is limited due to:- 缺少最大大小类型。
- 缺少本机memsize类型。
- LP64(在类Unix系统上)和LLP64(在Windows上)数据之间的任意选择64位系统上的模型。
- Lack of maximum sizes for these types.
- Lack of a native memsize type.
- The arbitrary choice between LP64 (on Unix-like systems) and LLP64 (on Windows) data models on 64-bit systems.
至于为什么会有这样的许多冗余类型定义固定宽度(
WORD
,DWORD
,__ int64
,gint64
,FINT64
等)和memsize(INT_PTR
,LPARAM
,VPTRDIFF
等)整数类型,主要是因为< stdint.h>
在C开发中来得很晚,人们仍在使用不支持它的旧编译器,因此库需要定义自己的编译器。 C ++有这么多字符串类的原因相同。As for why there are so many redundant typedefs of fixed-width (
WORD
,DWORD
,__int64
,gint64
,FINT64
, etc.) and memsize (INT_PTR
,LPARAM
,VPTRDIFF
, etc.) integer types, it's mainly because<stdint.h>
came late in C's development, and people are still using older compilers that don't support it, so libraries need to define their own. Same reason why C++ has so many string classes.这篇关于为什么C提供的整数类型对于任何项目都不够好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-