哪个初始化程序适用于int64_t?

时间:2021-12-22 12:09:37

I like to initialize my variables to some "dummy" value and have started to use int64_t and uint64_t. So far, it looks like there are at least three ways I could initialize an int64_t to a particular value (and with slight changes for the unsigned equivalent):

我喜欢将我的变量初始化为一些“虚拟”值,并开始使用int64_t和uint64_t。到目前为止,看起来至少有三种方法可以将int64_t初始化为特定值(并且对于无符号的等价物稍有更改):

int64_t method_one   = 0;
int64_t method_two   = 0LL;
int64_t method_three = INT64_C(0);

I use GCC and target OS X and Linux. I'd like to pick a method that aims for ease of portability and clarity — but correctness, above all. Am I overthinking this, or is there a "best" or "most recommended" approach for initializing this variable type, for any particular value I throw at it (which is within its bounds, of course)?

我使用GCC并针对OS X和Linux。我想选择一种旨在简化便携性和清晰度的方法 - 但最重要的是正确性。我是否过度思考这个,或者是否有一个“最佳”或“最推荐”的方法来初始化这个变量类型,对于我抛出的任何特定值(当然,它在其范围内)?

3 个解决方案

#1


8  

int64_t method_one   = 0;

...is perfectly reasonable. C99 (see e.g. draft here; yes, I know it's not the most recent standard any more, but it's the one that introduced the int<N>_t types) says that:

......完全合情合理。 C99(参见例如这里的草案;是的,我知道它不再是最新的标准了,但它是引入int _t类型的那个)说:

  • the 0 has type int (§6.4.4.1 para.5);
  • 0的类型为int(§6.4.4.1para.5);
  • the type of the expression is int64_t (§6.5.16 para.3);
  • 表达式的类型是int64_t(§6.5.16第3段);
  • the type of the right-hand side will be converted to the type of the expression (§6.5.16.1 para.2);
  • 右侧的类型将转换为表达式的类型(§6.5.16.1para.2);
  • this conversion will not change the value (§6.3.1.3 para.1).
  • 此转换不会改变该值(§6.3.1.3第1段)。

So there's nothing wrong with that at all, and the lack of additional clutter makes it the most readable of the options when initialising to 0 or anything else in the range of an int.

因此,根本没有任何问题,并且当初始化为0或int范围内的任何其他内容时,缺少额外的混乱使其成为最可读的选项。

int64_t method_two   = 0LL;

int64_t is not guaranteed to be the same as long long; however, this should in fact work portably for any signed 64-bit value as well (and similarly ULL for unsigned 64-bit values): long long (and unsigned long long) should be at least 64 bits in a C99-compliant implementation (§5.2.4.2.1), so LL (and ULL) should always be safe for initialising 64-bit values.

int64_t不保证与long long相同;但是,实际上这对于任何带符号的64位值都是可移植的(对于无符号的64位值也是类似的ULL):在符合C99的实现中,long long(和无符号long long)应该至少为64位( §5.2.4.2.1),因此LL(和ULL)应始终安全地初始化64位值。

int64_t method_three = INT64_C(0);

This is arguably a better option for values which may be outside the range of an int, as it expresses the intent more clearly: INT64_C(n) will expand to something appropriate for any n in (at least) a 64-bit range (see §7.18 in general, and particularly §7.8.4.1).

对于可能超出int范围的值,这可以说是更好的选择,因为它更清楚地表达了意图:INT64_C(n)将扩展到适合于(至少)64位范围内的任何n的值(参见§7.18一般,特别是§7.8.4.1)。


In practice, I might well use any of the above, depending on context. For example:

在实践中,我可能会使用上述任何一种,具体取决于具体情况。例如:

uint64_t counter = 0;

(Why add unnecessary clutter?)

(为什么要添加不必要的混乱?)

uint64_t some_bit = 1ULL << 40;

(1 << 40 simply won't work unless int is unusually wide; and UINT64_C(1) << 40 seems less readable to me here.)

(1 << 40根本不起作用,除非int异常宽;而UINT64_C(1)<< 40在这里似乎不太可读。)

uint64_t some_mask = UINT64_C(0xFF00FF00FF00FF00);

(In this case, explicitly calling out the value as a 64-bit constant seems more readable to me than writing 0xFF00FF00FF00FF00ULL.)

(在这种情况下,显式地将值作为64位常量调用似乎比写入0xFF00FF00FF00FF00ULL更具可读性。)

#2


6  

Personnally, I would use the third, which is the most portable way to achieve this.

个人而言,我会使用第三种,这是实现这一目标的最便携方式。

#include <stdint.h>

int64_t method_three  = INT64_C(0);
uint64_t method_three = UINT64_C(0);

Anyway, I don't think it's a very important thing.

无论如何,我认为这不是一件非常重要的事情。

#3


0  

According to the ANSI C standard, the suffix for a long long int and unsigned long long int is LL and ULL respectively:

根据ANSI C标准,long long int和unsigned long long int的后缀分别为LL和ULL:

octal or hexadecimal suffixed by ll or LL long long int, unsigned long long int decimal, octal, or hexadecimal suffixed by both u or U, and ll or LL unsigned long long int

八进制或十六进制,后缀为ll或LL long long int,unsigned long long int decimal,octal或hexadecimal,后缀为u或U,以及ll或LL unsigned long long int

If you know that int64_t is defined as:

如果你知道int64_t被定义为:

typedef signed long long int int64_t

Then method two is most definitely the correct one:

方法二绝对是正确的方法:

int64_t method_two   = 0LL;
uint64_t method_two   = 0ULL;

Edit:

编辑:

Keeping in mind the portability issues, and the fact that it's not guaranteed to be defined as long long, then it would be better to use the third method:

牢记可移植性问题,以及不能保证长时间定义的事实,那么使用第三种方法会更好:

INT64_C()
UINT64_C()

#1


8  

int64_t method_one   = 0;

...is perfectly reasonable. C99 (see e.g. draft here; yes, I know it's not the most recent standard any more, but it's the one that introduced the int<N>_t types) says that:

......完全合情合理。 C99(参见例如这里的草案;是的,我知道它不再是最新的标准了,但它是引入int _t类型的那个)说:

  • the 0 has type int (§6.4.4.1 para.5);
  • 0的类型为int(§6.4.4.1para.5);
  • the type of the expression is int64_t (§6.5.16 para.3);
  • 表达式的类型是int64_t(§6.5.16第3段);
  • the type of the right-hand side will be converted to the type of the expression (§6.5.16.1 para.2);
  • 右侧的类型将转换为表达式的类型(§6.5.16.1para.2);
  • this conversion will not change the value (§6.3.1.3 para.1).
  • 此转换不会改变该值(§6.3.1.3第1段)。

So there's nothing wrong with that at all, and the lack of additional clutter makes it the most readable of the options when initialising to 0 or anything else in the range of an int.

因此,根本没有任何问题,并且当初始化为0或int范围内的任何其他内容时,缺少额外的混乱使其成为最可读的选项。

int64_t method_two   = 0LL;

int64_t is not guaranteed to be the same as long long; however, this should in fact work portably for any signed 64-bit value as well (and similarly ULL for unsigned 64-bit values): long long (and unsigned long long) should be at least 64 bits in a C99-compliant implementation (§5.2.4.2.1), so LL (and ULL) should always be safe for initialising 64-bit values.

int64_t不保证与long long相同;但是,实际上这对于任何带符号的64位值都是可移植的(对于无符号的64位值也是类似的ULL):在符合C99的实现中,long long(和无符号long long)应该至少为64位( §5.2.4.2.1),因此LL(和ULL)应始终安全地初始化64位值。

int64_t method_three = INT64_C(0);

This is arguably a better option for values which may be outside the range of an int, as it expresses the intent more clearly: INT64_C(n) will expand to something appropriate for any n in (at least) a 64-bit range (see §7.18 in general, and particularly §7.8.4.1).

对于可能超出int范围的值,这可以说是更好的选择,因为它更清楚地表达了意图:INT64_C(n)将扩展到适合于(至少)64位范围内的任何n的值(参见§7.18一般,特别是§7.8.4.1)。


In practice, I might well use any of the above, depending on context. For example:

在实践中,我可能会使用上述任何一种,具体取决于具体情况。例如:

uint64_t counter = 0;

(Why add unnecessary clutter?)

(为什么要添加不必要的混乱?)

uint64_t some_bit = 1ULL << 40;

(1 << 40 simply won't work unless int is unusually wide; and UINT64_C(1) << 40 seems less readable to me here.)

(1 << 40根本不起作用,除非int异常宽;而UINT64_C(1)<< 40在这里似乎不太可读。)

uint64_t some_mask = UINT64_C(0xFF00FF00FF00FF00);

(In this case, explicitly calling out the value as a 64-bit constant seems more readable to me than writing 0xFF00FF00FF00FF00ULL.)

(在这种情况下,显式地将值作为64位常量调用似乎比写入0xFF00FF00FF00FF00ULL更具可读性。)

#2


6  

Personnally, I would use the third, which is the most portable way to achieve this.

个人而言,我会使用第三种,这是实现这一目标的最便携方式。

#include <stdint.h>

int64_t method_three  = INT64_C(0);
uint64_t method_three = UINT64_C(0);

Anyway, I don't think it's a very important thing.

无论如何,我认为这不是一件非常重要的事情。

#3


0  

According to the ANSI C standard, the suffix for a long long int and unsigned long long int is LL and ULL respectively:

根据ANSI C标准,long long int和unsigned long long int的后缀分别为LL和ULL:

octal or hexadecimal suffixed by ll or LL long long int, unsigned long long int decimal, octal, or hexadecimal suffixed by both u or U, and ll or LL unsigned long long int

八进制或十六进制,后缀为ll或LL long long int,unsigned long long int decimal,octal或hexadecimal,后缀为u或U,以及ll或LL unsigned long long int

If you know that int64_t is defined as:

如果你知道int64_t被定义为:

typedef signed long long int int64_t

Then method two is most definitely the correct one:

方法二绝对是正确的方法:

int64_t method_two   = 0LL;
uint64_t method_two   = 0ULL;

Edit:

编辑:

Keeping in mind the portability issues, and the fact that it's not guaranteed to be defined as long long, then it would be better to use the third method:

牢记可移植性问题,以及不能保证长时间定义的事实,那么使用第三种方法会更好:

INT64_C()
UINT64_C()