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

时间:2012-11-07 17:39:09

标签: c gcc int64

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

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

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

3 个答案:

答案 0 :(得分:8)

int64_t method_one   = 0;

......非常合理。 C99(参见例如草案here;是的,我知道它不再是最新的标准,但它是引入int<N>_t类型的那个)说:

  • 0的类型为int(§6.4.4.1第5段);
  • 表达式的类型为int64_t(§6.5.16第3段);
  • 右侧的类型将转换为表达式的类型(§6.5.16.1para.2);
  • 此转换不会更改该值(§6.3.1.3第1段)。

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

int64_t method_two   = 0LL;

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

int64_t method_three = INT64_C(0);

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


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

uint64_t counter = 0;

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

uint64_t some_bit = 1ULL << 40;

1 << 40根本不起作用,除非int异常宽; UINT64_C(1) << 40对我来说似乎不太可读。)

uint64_t some_mask = UINT64_C(0xFF00FF00FF00FF00);

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

答案 1 :(得分:7)

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

#include <stdint.h>

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

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

答案 2 :(得分:0)

根据ANSI C标准,long long intunsigned long long int的后缀分别为LLULL

  

八进制或十六进制,后缀为 ll或LL long long int,unsigned   long long int十进制,八进制或十六进制,后缀为 u或U,   和ll或LL unsigned long long int

如果您知道int64_t被定义为:

typedef signed long long int int64_t

然后方法二肯定是正确的:

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

修改

请记住可移植性问题,以及不能保证定义为long long的事实,那么最好使用第三种方法:

INT64_C()
UINT64_C()