fundamental integral types or extended integral types

我们先通过下图,来了解可以跨平台使用的整数类型:

之所以我们需要以上各种明确指定宽度的int类型是因为int类型本身比较特殊,其具体的字节数同机器字长和编译器有关(标准并没有规定其具体所占的字节数)。

因此如果要保证移植性,我们应该尽量使用上图中带宽度的int类型。这种数据类型在所有平台下都分配相同的字节,因此在移植上不存在问题。

需要注意的问题

我们以整数类型int64_t为例来说明。我们都知道,int64_t用来表示64位整数,在32位系统中是long long int,在64位系统中是long int,所以打印int64_t的格式化方法如下:

printf("%ld" , value);  // 64bit OS
printf("%lld", value); // 32bit OS

那么这样在32位系统和64位系统中,编译相同的代码,就有可能会出错。跨平台的方法是使用PRId64来格式化输出,如下:

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif #include <inttypes.h> printf("%" PRId64 "\n", value);

具体可以参看下图:

注意:上述宏定义针对C语言,如果C++需要使用PRId64等宏,需要定义一个__STDC_FORMAT_MACROS宏显示打开它。具体可以参见/usr/include/inttypes.h中宏__STDC_FORMAT_MACROS的定义,如下:

/* The ISO C99 standard specifies that these macros must only be
defined if explicitly requested. */
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS # if __WORDSIZE == 64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
# else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
# endif /* Macros for printing format specifiers. */ /* Decimal notation. */
# define PRId8 "d"
# define PRId16 "d"
# define PRId32 "d"
# define PRId64 __PRI64_PREFIX "d"

举例

MUDUO开源库中也使用了上文所提到的方式,源码如下:

#include <muduo/base/Timestamp.h>

#include <sys/time.h>
#include <stdio.h> #ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif #include <inttypes.h> #include <boost/static_assert.hpp> using namespace muduo; BOOST_STATIC_ASSERT(sizeof(Timestamp) == sizeof(int64_t)); Timestamp::Timestamp(int64_t microseconds)
: microSecondsSinceEpoch_(microseconds)
{
} string Timestamp::toString() const
{
char buf[32] = {0};
int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond;
int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond;
snprintf(buf, sizeof(buf)-1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds);
return buf;
} string Timestamp::toFormattedString(bool showMicroseconds) const
{
char buf[32] = {0};
time_t seconds = static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
struct tm tm_time;
gmtime_r(&seconds, &tm_time); if (showMicroseconds)
{
int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d",
tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
microseconds);
}
else
{
snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d",
tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
}
return buf;
} Timestamp Timestamp::now()
{
struct timeval tv;
gettimeofday(&tv, NULL);
int64_t seconds = tv.tv_sec;
return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
} Timestamp Timestamp::invalid()
{
return Timestamp();
}

说明

对于支持C++11标准的编译器,不用添加宏__STDC_FORMAT_MACROS,也可以直接编译通过。

参考文献

1. http://www.cplusplus.com/reference/cinttypes/?kw=inttypes.h

2. http://www.cprogramdevelop.com/4787258/

3. https://github.com/chenshuo/muduo/blob/master/muduo/base/Timestamp.cc

Integral类型的跨平台使用的更多相关文章

  1. C++primer读书笔记9-转换和类类型

    有时指定自己的类类型来表示某些类型的数据,如SmallInt,然后在为了便于计算将指定一个转换算,类类型,在某些情况下,自己主动转换为指定的类型 <1>转换操作符 operator typ ...

  2. 第19课 类型萃取(3)_类型选择的traits

    1. std::conditional (1)原型:template <bool Cond, class T, class F> struct conditional; //根据条件获取T ...

  3. 跨平台编程相关技术资料及笔记.md

    目录 跨平台编程技术选型 ## 需求 最终选定的技术方案:uni-app 混合或跨平台编程相关资料 ## uni-app 官网 相关资料 个人笔记 个人经验 ## taro 官网 相关资料 ## Ch ...

  4. Python 基础【第十篇】内置类型

    一.integral 类型 Python提供了两种integral类型,即int(整数)与bool(布尔值). 1.1.整数 整数的相关运算符.函数.数据类型转换 1.1.1.整数的运算符 前面已经讲 ...

  5. C++一些注意点之转换操作符

    转换操作符定义 类可通过一个实参调用的非explicit构造函数定义一个隐式转换(其他类型—>类类型).当提供了实参类型的对象而需要一个类类型的对象时,编译器将使用该转换.这种构造函数定义了到类 ...

  6. Libevent教程001: 简介与配置

    本文内容大致翻译自 libevent-book, 但不是照本翻译. 成文时, libevent最新的稳定版为 2.1.8 stable. 即本文如无特殊说明, 所有描述均以 2.1.8 stable ...

  7. 『集群』006 Slithice 后期改进 和 Slithice可能存在的BUG

    Slithice 后期改进 和 Slithice可能存在的BUG Slithice 可能存在的 BUG: >Slithice 暂时 没有 对 循环调度 进行控制:不正确的 配置 可能导致 调度死 ...

  8. 【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员

    转自:forbids in-class initialization of non-const static member不能在类内初始化非const static成员 今天写程序,出现一个新错误,好 ...

  9. java中文GBK和UTF-8编码转换乱码的分析

    原文:http://blog.csdn.net/54powerman/article/details/77575656 作者:54powerman 一直以为,java中任意unicode字符串,可以使 ...

随机推荐

  1. 联想Z470安装10.11懒人版成功!!特此分享!!

    折腾黑苹果也断断续续好几个月了,在远景也爬了好多贴,遇到问题基本上靠自己解决,自己组的台式机已基本完美,大学期间买的联想Z470现在是“食之无味,弃之可惜”,想想也来试试装个黑苹果玩玩,之前装过10. ...

  2. Sharepoint 2010 RBS 的安装和配置

    基本上按照微软官方的配置方法配置就行了. 给下地址:微软官方     涂大神 找RBS的安装文件也是个问题,微软的链接好像失效了.我使用的是RBS下载.这里也有. 我的环境是数据库两台故障群集转移,微 ...

  3. arm-elf-gcc汇编代码个人理解

    arm-elf-gcc汇编代码个人理解 有关arm-elf-gcc的安装使用问题请参照本人博客的另一篇文章http://www.cnblogs.com/wsine/p/4664503.html 由于各 ...

  4. java判断某个字符串包含某个字符串的个数

    /** * 判断str1中包含str2的个数 * @param str1 * @param str2 * @return counter */ public static int countStr(S ...

  5. VC++编程之对话框贴图

    基于对话框的程序写好后,为对话框贴上个图片让界面更加美观(我承认做界面,MFC显得力不从心,不如QT). 其实很简单,我们以位图为例,选好我们需要的位图资源(bmp),假若自己的图片不是位图资源,可以 ...

  6. U3D 随笔

    http://unity3d.com/ 资源站 http://docs.unity3d.com/Documentation/ScriptReference/index.html  最新API new ...

  7. JavaScript 函数调用

    JavaScript 函数有 4 种调用方式. 每种方式的不同方式在于 this 的初始化. this 关键字 一般而言,在Javascript中,this指向函数执行时的当前对象. 注意 this ...

  8. 【转载】MyBatis之传入参数

    原文地址:http://blog.csdn.net/liaoxiaohua1981/article/details/6862764 在MyBatis的select.insert.update.dele ...

  9. 【BZOJ】【3172】【TJOI2013】单词

    AC自动机 Orz zyf 玛雅一开始连题意都没看懂……意思就是给你一篇文章的N个单词,问每个单词在这篇文章中各出现了几次?(这篇文章=N个单词) 那么我们建个AC自动机……对于每个单词来说,它出现的 ...

  10. Visual Studio快捷键设置

    1.查看当前快捷键:环境-键盘-按快捷键2.文本编辑器-C#-显示-行号3.文本编辑器-C#-制表符-插入空格4.文本编辑器-所有语言-没有选定内容时对空行应用剪切或复制命令5.Ctrl+Shift- ...