为什么macOS把uint64当作unsigned long long,而Ubuntu把uint64当作unsigned long?

8 浏览
0 Comments

为什么macOS把uint64当作unsigned long long,而Ubuntu把uint64当作unsigned long?

C99标准具有类似int64_t的字节大小的整数类型。我目前正在使用Windows的%I64d格式(或无符号的%I64u),如下所示:\n

#include 
#include 
int64_t my_int = 999999999999999999;
printf("这是我的整数: %I64d\n", my_int);

\n但是我得到了这个编译器警告:\n

警告:格式‘%I64d’预期类型为‘int’,但参数2的类型为‘int64_t’

\n我尝试了以下方式:\n

printf("这是我的整数: %lld\n", my_int); // 长长型十进制

\n但是我得到了相同的警告。我正在使用这个编译器:\n

~/dev/c$ cc -v
使用内建规格。
目标: i686-apple-darwin10
配置为: /var/tmp/gcc/gcc-5664~89/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
线程模型:posix
gcc版本 4.2.1 (Apple Inc. build 5664)

\n在不出现警告的情况下,我应该使用哪种格式来打印my_int变量?

0
0 Comments

在C99标准中,%j长度修饰符可以与printf函数系列一起使用,用于打印int64_t和uint64_t类型的值。根据我的Linux系统上的printf(3)文档(该man页面明确指出j用于表示转换为intmax_t或uintmax_t;在我的stdint.h中,int64_t和intmax_t的typedef方式完全相同,uint64_t也是如此),如果%jd打印intmax_t,则正确的调用方式应该是printf("a=%jd (0x%jx)", (intmax_t) a, (intmax_t) a)。没有保证int64_t和intmax_t是相同的类型,如果它们不同,则行为是未定义的。

在将它们传递给printf之前,您可以将int64_t值显式转换为intmax_t,以便以可移植的方式使用%jd打印int64_t值:printf("a=%jd\n", (intmax_t)a)。这样可以避免使用宏(在我看来,它们很丑陋)。当然,这需要假设您的实现支持%jd、int64_t和intmax_t,它们都是C99新增的内容。

宏让我们能够在不将值转换为更宽的类型的情况下打印这些类型的值,这在某些情况下可能会带来显著的性能影响。在没有重载的情况下,您必须在宏中编码类型名称。在I/O开销已经足够大的情况下,整数转换可能会被忽略,但在某些系统上,转换为[u]intmax_t可能是昂贵的。我无法想到除了更改语言之外,还有其他更好的方法来实现相同的效果(尽管您可能可以使用_Generic来编写一些东西)。

也许,但如果您想涵盖奇怪的系统,就不能假设uint64_t存在。您可以假设uint_least64_t和uint_fast64_t存在,但如果格式说明符是针对它们中的一个,则可能需要对uint64_t参数进行强制转换。对于8、16、32位也是一样的。

我猜他们的理由是避免在printf实现中产生额外的开销,引入更多的长度修饰符会导致这种开销。他们的解决方案虽然很丑陋,但在编译时将其解析为已支持的修饰符之一。

0
0 Comments

在C语言中,不同的操作系统可能对于uint64的数据类型有不同的要求。具体来说,macOS希望将uint64表示为unsigned long long,而Ubuntu希望将uint64表示为unsigned long。

这个问题出现的原因是因为不同的操作系统对于数据类型的定义有所不同,导致在代码编写中可能会出现兼容性问题。为了解决这个问题,可以使用一些方法。

一种解决方法是使用C99标准中的头文件来定义uint64类型的变量,并使用相应的格式打印输出。例如,可以使用int64_t类型来定义uint64变量,并使用% PRId64格式进行打印输出。

另一种解决方法是使用强制类型转换。可以将uint64类型的变量转换为所需的数据类型,然后使用相应的打印格式进行输出。例如,可以将uint64变量转换为long类型或long long类型,并使用% ld或% lld格式进行打印输出。

对于那些仍然使用C89标准的实现(特别是Visual Studio),可以使用开源的(和)来解决此问题。从code.google.com链接下载msinttypes头文件,并在代码中加入#define __STDC_FORMAT_MACROS来使用这个头文件。

需要注意的是,__STDC_FORMAT_MACROS宏只在C++中需要使用。在链接的代码中,对于C语言,这些定义被放在一个#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)的条件编译块中。

总结起来,解决macOS和Ubuntu对于uint64数据类型的不同要求的方法包括使用C99标准的头文件、使用强制类型转换,以及在C89标准中使用开源的来解决兼容性问题。

0
0 Comments

macOS和Ubuntu对于uint64的类型的要求不同,macOS希望将uint64视为unsigned long long,而Ubuntu希望将uint64视为unsigned long。这个问题的原因是由于不同平台对于数据类型的定义和长度的差异导致的。为了解决这个问题,可以使用inttypes.h头文件中提供的宏来正确地打印uint64类型的值。在代码中,可以使用PRIu64宏来打印uint64类型的值,例如printf("%" PRIu64 "\n", t)。另外,如果在Linux上使用C++,还需要在包含inttypes.h之前定义__STDC_FORMAT_MACROS宏。通过使用这些宏,可以保证代码在不同平台上的可移植性。

总结起来,针对不同平台对于uint64类型的定义和打印方式的差异,可以使用inttypes.h中提供的宏来解决这个问题。这些宏可以确保代码在不同平台上的正确性和可移植性。

0