C++ uint8、uint16等的使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15062386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Usage of uint8, uint16 etc
提问by NeonGlow
Currently I am working with a code base (C, C++ mixed) targeted for a 32 bit MIPS platform. The processor is a fairly modern one [just to mention that we have a good amount of processing power and memory].
目前我正在使用针对 32 位 MIPS 平台的代码库(C、C++ 混合)。处理器是一个相当现代的处理器[只是提到我们拥有大量的处理能力和内存]。
The code base uses data types like uint8[1 byte wide unsigned integer], uint16[2 byte wide unsigned integer], uint32[4 byte wide unsigned integer] etc.
代码库使用诸如 uint8[1 字节宽的无符号整数]、uint16[2 字节宽的无符号整数]、uint32[4 字节宽的无符号整数]等数据类型。
I know how the usage of these constructs are helpful while porting the code to different platforms.
我知道在将代码移植到不同平台时如何使用这些构造是有帮助的。
My questions are:
我的问题是:
What is the use of/benefit in using a uint16 where an uint32 will also suffice(if, there is any)?
Will there be any savings in memory usage in using shorter data types (considering data alignment)?
If it is to save a few bytes of memory, is it something sensible to do in modern hardware?
使用 uint16 的用途/好处是什么,其中 uint32 也足够了(如果有的话)?
使用较短的数据类型(考虑数据对齐)是否会节省内存使用量?
如果是为了节省几个字节的内存,在现代硬件中这样做是否明智?
回答by Alexey Frunze
What is the use of/benefit in using a uint16 where an uint32 will also suffice(if, there is any)?
使用 uint16 的用途/好处是什么,其中 uint32 也足够了(如果有的话)?
If those uint16s
are parts of arrays or structures, you can save memory and perhaps be able to handle larger data sets than with uint32s
in those same arrays or structures. It really depends on your code.
如果这些uint16s
是数组或结构的一部分,则可以节省内存,并且可能能够处理比uint32s
相同数组或结构中更大的数据集。这真的取决于你的代码。
Data protocols and file formats may use uint16s
and it may not be correct to use uint32s
instead. This depends on the format and semantics (e.g. if you need values to wrap around from 65535 to 0, uint16
will do that automatically while uint32
won't).
可能会使用数据协议和文件格式,但使用uint16s
它可能不正确uint32s
。这取决于格式和语义(例如,如果您需要将值从 65535 环绕到 0,uint16
则会自动执行,而uint32
不会)。
OTOH, if those uint16s
are just single local or global variables, replacing them with 32-bit ones might make no significant difference because they are likely to occupy the same space due to alignment and they are passed as 32-bit parameters (on the stack or in registers) on MIPS anyway.
OTOH,如果这些uint16s
只是单个局部或全局变量,用 32 位变量替换它们可能没有显着差异,因为它们可能由于对齐而占据相同的空间,并且它们作为 32 位参数传递(在堆栈或在寄存器中)无论如何都在 MIPS 上。
Will there be any savings in memory usage in using shorter data types (considering data alignment)?
使用较短的数据类型(考虑数据对齐)是否会节省内存使用量?
There may be savings, especially when uint16s
are parts of many structures or elements of big arrays.
可能会有节省,特别是当它uint16s
是大数组的许多结构或元素的一部分时。
If it is to save a few bytes of memory, is it something sensible to do in modern hardware?
如果是为了节省几个字节的内存,在现代硬件中这样做是否明智?
Yes, you lower the memory bandwidth (which is always a good thing) and you often lower various cache misses (data caches and TLB) when you operate on less data.
是的,您降低了内存带宽(这总是一件好事),并且当您对较少的数据进行操作时,通常会降低各种缓存未命中(数据缓存和 TLB)。
回答by Clifford
First of all if you have types such as uint16 defined, where are they defined? They are not standard types, so will be defined in some proprietary header - maybe yours or may be supplied by some third party library; in which case you have to ask yourself how portable that code is, and whether you are creating a dependency that might not make sense in some other application.
首先,如果定义了 uint16 等类型,它们是在哪里定义的?它们不是标准类型,因此将在某些专有标头中定义 - 可能是您的或可能由某些第三方库提供;在这种情况下,您必须问自己该代码的可移植性如何,以及您是否正在创建在其他应用程序中可能没有意义的依赖项。
Another problem is that many libraries (ill-advisedly IMO) define such types with various names such as UINT16, uint16, U16 UI16 etc. that it becomes somewhat of a nightmare ensuring type agreement and avoiding name clashes. If such names aredefined, they should ideally be placed in a namespace or given a library specific prefix to indicate what library they were defined for use with, for example rtos::uint16
to rtos_uint16
.
另一个问题是,许多库(不明智的 IMO)使用各种名称(例如 UINT16、uint16、U16 UI16 等)定义此类类型,这在某种程度上变成了确保类型一致并避免名称冲突的噩梦。如果这样的名字被定义,他们应该理想地被放置在一个命名空间或给定库特定的前缀以表示它们与使用被定义什么库,例如rtos::uint16
到rtos_uint16
。
Since the ISO C99 standard library provides standard bit-length specific types in stdint.h, you should prefer their use over any defined in a proprietary or third-party header. These types have a _t
suffix, e.g. uint16_t
. In C++ they may be placed in the std::
namespace (though that is not a given since the header was introduced in C99).
由于 ISO C99 标准库在 stdint.h 中提供了标准位长度特定类型,因此您应该更喜欢使用它们,而不是在专有或第三方标头中定义的任何类型。这些类型有一个_t
后缀,例如uint16_t
。在 C++ 中,它们可能被放置在std::
命名空间中(尽管这不是给定的,因为头文件是在 C99 中引入的)。
1] What is the use of/benefit in using a uint16 where an uint32 will also suffice(if, there is any)?
1] 使用 uint16 的用途/好处是什么,其中 uint32 也足够了(如果有的话)?
Apart from my earlier advice to prefer stdint.h
's uint16_t
, there are at least two legitimate reasons to use length specific types:
除了我之前建议使用stdint.h
's 之外uint16_t
,至少有两个合理的理由可以使用特定于长度的类型:
- To match a specific hardware register width.
- To enforce a common and compatible API across different architectures.
- 匹配特定的硬件寄存器宽度。
- 跨不同架构实施通用且兼容的 API。
2] Will there be any savings in memory usage in using shorter data types (considering data alignment)?
2] 使用较短的数据类型(考虑数据对齐)是否会节省内存使用量?
Possibly, but if memory is not your problem, that is not a good reason to use them. Worth considering perhaps for large data objects or arrays, but applying globally is seldom worth the effort.
可能,但如果内存不是你的问题,那不是使用它们的好理由。对于大型数据对象或数组,可能值得考虑,但在全球范围内应用很少值得付出努力。
3] If it is to save a few bytes of memory, is it something sensible to do in modern hardware?
3] 如果是为了节省几个字节的内存,在现代硬件中这样做是否明智?
See [2]. "Modern hardware" however does not necessarily imply large resources; there are plenty of 32 bit ARM Cortex-M devices with only a few Kb of RAM for example. That is more about die space, cost and power consumption than it is about age of design or architecture.
见[2]。然而,“现代硬件”并不一定意味着大量资源;例如,有很多 32 位 ARM Cortex-M 设备只有几 Kb 的 RAM。这更多是关于芯片空间、成本和功耗,而不是关于设计或架构的时代。
回答by Alex Chamberlain
cstdint
has loads of typedef
s for different purposes.
cstdint
有很多typedef
s 用于不同的目的。
intN_t
for a specific widthint_fastN_t
for the fastest integer, which has at least N bitsint_leastN_t
for the smallest integer, which has at least N bits- Their
unsigned
equivalents
intN_t
对于特定宽度int_fastN_t
对于最快的整数,它至少有 N 位int_leastN_t
对于最小的整数,它至少有 N 位- 他们的
unsigned
等价物
You should choose depending on your circumstances. Storing thousands in a std::vector
and not doing loads of computation? intN_t
is probably your man. Need fast computation on a small number of integers? int_fastN_t
is probably your guy.
你应该根据你的情况来选择。在 a 中存储数千个std::vector
而不进行大量计算?intN_t
可能是你的男人。需要对少量整数进行快速计算?int_fastN_t
可能是你的人。
回答by Aki Suihkonen
One has to check the produced machine code / assembler to verify there are any saving of code. In RISC type architectures the typical immediate is 16-bit, but using uint16_t will anyway consume a full 32-bit register -- thus, if using int types, but committing to use values near zero will produce the same results and being more portable.
必须检查生成的机器代码/汇编程序以验证是否有任何代码保存。在 RISC 类型体系结构中,典型的立即数是 16 位,但使用 uint16_t 无论如何都会消耗完整的 32 位寄存器——因此,如果使用 int 类型,但承诺使用接近零的值将产生相同的结果并且更易于移植。
IMO saving memory is worthwhile in modern platforms too. Tighter code leads to e.g. better battery life and more fluent UX. However, I'd suggest micro-managing the size only when working with (large) arrays, or when the variable maps to some real HW resource.
IMO 节省内存在现代平台中也是值得的。更紧凑的代码可以带来更长的电池寿命和更流畅的用户体验。但是,我建议仅在使用(大型)数组时,或者当变量映射到某个真实的硬件资源时,才对大小进行微观管理。
ps. Compilers are smart, but the folks writing them work at the moment making them even better.
附:编译器很聪明,但现在编写它们的人正在使它们变得更好。
回答by paper.plane
Ans. 1. Software has certain requirements and specifications which strictly tells to take only 8/16-bits of a parameter while encoding/decoding or some other certain use. So, even if u assign a value bigger than 127 into a u8 say, it trims the data automatically for you.
答。1. 软件有一定的要求和规范,严格要求在编码/解码或其他某些特定用途时只取参数的 8/16 位。因此,即使您将大于 127 的值分配到 u8 中,它也会自动为您修剪数据。
Ans. 2. We should not forget that our compilers are way beyond intelligent to do the optimization, be it memory or complexity. So it is always recommended to use a smaller memory when possible.
答。2. 我们不应该忘记,我们的编译器在进行优化方面远远超出了智能,无论是内存还是复杂性。因此,始终建议尽可能使用较小的内存。
Ans. 3. Of course saving memory makes sense on modern h/w.
答。3.当然,在现代硬件上节省内存是有意义的。
回答by Nikos C.
Using exact width integer types like int32_t
and friends is useful in avoiding sign extension bugs between platforms that have different sizes for int
and long
. These can occur when applying bit masks or when bit shifting, for example. If you do these operations on a long
for example, and your code works for a 32-bit long
, it might break for a 64-bit long
. If on the other hand you use a uint32_t
, you know exactly what results you'll get regardless of platform.
使用像int32_t
和 朋友这样的精确宽度整数类型有助于避免具有不同大小的平台之间的符号扩展错误int
和long
。例如,在应用位掩码或位移时可能会发生这些情况。long
例如,如果您在 a 上执行这些操作,并且您的代码适用于 32 位long
,则它可能会中断 64 位long
。另一方面,如果您使用 a uint32_t
,则您确切地知道无论平台如何都会得到什么结果。
They're also useful for exchanging binary data between platforms, where you only have to worry about the endianness of the stored data and not the bit width; if you write an int64_t
to a file, you know that on another platform you can read it and store that into an int64_t
. If you were writing out a long
instead that's 64 bits on one platform, you might end up needing a long long
on another platform because long
there is only 32 bits.
它们对于在平台之间交换二进制数据也很有用,您只需担心存储数据的字节序而不是位宽;如果您将 an 写入int64_t
文件,您就会知道在另一个平台上您可以读取它并将其存储到int64_t
. 如果您long
在一个平台上写出64 位的a ,那么您最终可能需要long long
在另一个平台上使用a ,因为long
只有 32 位。
Saving memory is usually not the reason, unless you're talking about very limited environments (embedded stuff) or large data sets (like an array with 50 million elements or such.)
节省内存通常不是原因,除非您谈论的是非常有限的环境(嵌入的东西)或大型数据集(例如具有 5000 万个元素的数组等。)
回答by Basile Starynkevitch
Using uint16_t
instead of uint32_t
is saving memory. It might also be a hardware constraint (e.g. some peripheral controller is really sending 16 bits!) However, it may not worth using it, because of cache and alignment considerations (you really have to benchmark).
使用uint16_t
而不是uint32_t
节省内存。它也可能是硬件限制(例如,某些外围控制器确实发送 16 位!)但是,由于缓存和对齐方面的考虑(您确实必须进行基准测试),它可能不值得使用。
回答by B?ови?
What is the use of/benefit in using a uint16 where an uint32 will also suffice(if, there is any)?
使用 uint16 的用途/好处是什么,其中 uint32 也足够了(如果有的话)?
There are CPUs where unsigned char
is 16-bit value. Unit testing such code would be difficult without the use of typedefs (uint16 is just a typedef for appropriate type).
有unsigned char
16 位值的CPU 。如果不使用 typedef(uint16 只是适当类型的 typedef),对此类代码进行单元测试将很困难。
Also, with the use of these typedefs, it is easier to build on different platforms without many problems.
此外,通过使用这些 typedef,可以更轻松地在不同平台上构建而不会出现很多问题。
Will there be any savings in memory usage in using shorter data types (considering data alignment)?
使用较短的数据类型(考虑数据对齐)是否会节省内存使用量?
No, that is not a point. If uint16
is a typedef for unsigned short
, then you can use unsigned short
everywhere, but you might get different types on different platforms.
不,这不是重点。如果uint16
是 for 的 typedef unsigned short
,那么你可以unsigned short
在任何地方使用,但你可能会在不同的平台上得到不同的类型。
Of course, use of a type that is smaller will reduce memory consumption. For example, using uint16 instead of uint32, but only if you use arrays.
当然,使用较小的类型会减少内存消耗。例如,使用 uint16 而不是 uint32,但前提是您使用数组。
If it is to save a few bytes of memory, is it something sensible to do in modern hardware?
如果是为了节省几个字节的内存,在现代硬件中这样做是否明智?
That depends on the platform :
这取决于平台:
- less memory usage means less cache misses
- if supported, there are SIMD functions which process 16-bit data
- 更少的内存使用意味着更少的缓存未命中
- 如果支持,有处理 16 位数据的 SIMD 函数
回答by L0j1k
The answers to your questions boils down to one key concept: How big is the data? If you are crunching a lot of it, then the benefit of using smaller data types is obvious. Think of it this way: Simply calculating the newly-discovered largest known prime could run you out of memory on a typical workstation. The number itself takes upwards of a gigabyte just to store. That doesn't include working up to calculating the actual number. If you were to use a thick data type instead of a thin one, you may be looking at two gigabytes instead. A simplistic example, but a good one nonetheless.
您的问题的答案归结为一个关键概念:数据有多大?如果您处理大量数据,那么使用较小数据类型的好处是显而易见的。可以这样想:简单地计算新发现的最大已知素数可能会使您在典型工作站上耗尽内存。这个数字本身就需要超过 1 GB 来存储。这不包括计算实际数字。如果您要使用厚数据类型而不是薄数据类型,您可能会看到 2 GB。一个简单的例子,但仍然是一个很好的例子。