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. php webservice soap

    http://www.cnblogs.com/phpdragon/archive/2012/06/10/2544171.html http://jeffxie.blog.51cto.com/13653 ...

  2. Qt的QTabelWidget

    QTableWidget的用法总结  http://blog.csdn.net/zb872676223/article/details/39959061 [Qt]在QTableWidget中添加QCh ...

  3. 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?

    在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...

  4. VS2013 help viewer搜索结果显示源码以及桌面独立运行help viewer

    安装好VS2013后,启动help viewer2.1在搜索栏中搜搜时结果会出现HTML源码. 要解决这个问题先来看看MINE,即Multipurpose Internet Mail Extensio ...

  5. hasOwnProperty与isPrototypeOf

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. css3 forwards、backwards、both

    animation-fill-mode 属性规定动画在播放之前或之后,其动画效果是否可见. none 不改变默认行为. forwards 当动画完成后,保持最后一个属性值(在最后一个关键帧中定义). ...

  7. Mac下的常用Shell命令

    今天介绍一下在Mac的终端中一些常用的Shell命令: 1.查看当前工作目录的完整路径 pwd (pwd的原意是:print work directiory,而不是密码password的意思,呵呵) ...

  8. Python中的计数(词频)

    1,对于list列表来说 a.用自定义函数来统计技术 def get_count(sequence): counts={} for x in sequence: if x in sequence: c ...

  9. 《我是一只it小小鸟》

    <我是一只it小小鸟>一书虽然内容不多,但里面的故事极其励志,耐人寻味.虽然只花不多的时间阅读这本书,它给我的影响将会伴随一生. 他们是来自不同的院校,或本科,或半路转行:工作在不同的场所 ...

  10. mysql--乱码

    不知道为什么utf8反而会乱码,每次都是设gbk,,唉这样写项目的时候也是有点问题的T  T set names gbk; 版权声明:本文为博主原创文章,未经博主允许不得转载.