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. azure 云服务证书下载方式

    打开地址自动下载证书,vs中项目-右键-发布-导入证书. https://manage.windowsazure.cn/publishsettings/index 在 Visual Studio 中打 ...

  2. golang反射初试

    golang反射来自Go AST(Abstract Syntax Tree). reflect操作更多像traverse AST. t := reflect.TypeOf(obj) 使用TypeOf( ...

  3. iOS 各种系统文件目录 临时,缓存,document,lib,归档,序列化

    /** 1:Documents:应用中用户数据可以放在这里,iTunes备份和恢复的时候会包括此目录 2:tmp:存放临时文件,iTunes不会备份和恢复此目录,此目录下文件可能会在应用退出后删除 3 ...

  4. Resizing the View(待续。。。。)

    在iOS开发的过程中,控件的大小和位置如何去安排是一个现在看来比较麻烦的事情,需要从上到下的通知和从下到上的调整.而这部分在整个开发过程中是比较重要的,但是却经常没有被掌握.如果将这部分掌握,不管界面 ...

  5. 引用类型a=b

    List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); Cache["Key ...

  6. C语言函数返回数组

    #include "stdio.h"/*int* set(int a,int *c){ int *b; b=malloc(sizeof(int)*3); c[0]=a; c[1]= ...

  7. Java-包

    定义包用package关键字. 1:对类文件进行分类管理. 2:给类文件提供多层名称空间. 如果生成的包不在当前目录下,需要最好执行classpath,将包所在父目录定义到classpath变量中即可 ...

  8. C++设计模式——代理模式

    前言 青春总是那样,逝去了才开始回味:大学生活也是在不经意间就溜走了,现在上班的时候,偶尔还会怀念大学时,大家在一起玩游戏的时光.大学喜欢玩游戏,但是可悲的校园网,速度能把人逼疯了:还好,后来搞了一个 ...

  9. 在windows下使用vs2013编译和调试mysql源代码

    1. 准备工作 1)OS:win10 + VS2013 2)mysql 源码(windows版):mysql-5.6.25.zip 3)perl tool:ActivePerl-5.16.3.1604 ...

  10. MySQL自动化安装(双主多从读写分离)

    shell #!/bin/bash # Create by # version 1.0 # // # # check out lockfile whether or not exist IsInput ...