[C] zlstdint(让VC、TC等编译器自动兼容C99的整数类型)V1.0。支持Turbo C++ 3等DOS下的编译器

作者:zyl910

  以前我曾为了让VC++等编译器支持C99的整数类型,便编写了c99int库来智能处理(http://www.cnblogs.com/zyl910/p/c99int_v102.html)。如今为了兼容Turbo C++ 3等DOS下的编译器,做了重大改变,不再适合沿用旧名,于是采用了zlstdint这个新名。

一、用法简介

  用法很简单——把z_stdint.h、z_inttyp.h这2个文件放到你的项目中,便可以正常的使用C99整数类型及相关的宏了。

  范例代码——

#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#define __STDC_FORMAT_MACROS

#include <stdio.h>

#include "z_stdint.h"
#include "z_inttyp.h"

/// main.
int main(int argc, char* argv[]) {
    uint8_t i8 = (uint8_t)INT8_C(-1);
    uint16_t i16 = (uint16_t)INT16_C(-1);
    uint32_t i32 = (uint32_t)INT32_C(-1);
#ifdef INT64_MAX
    uint64_t i64 = (uint64_t)INT64_C(-1);
#endif

#ifdef INT64_MAX
    printf("stdint:\t%" PRIu8 ", %" PRIu16 ", %" PRIu32 ", %" PRIu64 "\n", i8, i16, i32, i64);
#else
    printf("stdint:\t%" PRIu8 ", %" PRIu16 ", %" PRIu32 "\n", i8, i16, i32);
#endif
    return 0;
}

  由于旧编译器不支持64位整数类型,故根据INT64_MAX宏来判断是否支持。

二、改动详述

  为了支持Turbo C++ 3等DOS下的编译器,于是精心设计了头文件名,使其符合8.3文件名命名规则。文件名对应关系为——
z_stdint.h:对应C99标准中的“stdint.h”。
z_inttyp.h:对应C99标准中的“inttypes.h”。

  用“z_”的前缀表示它用于兼容C标准中的头文件,随后的6个字母是对应头文件的缩写。

  由于Turbo C++ 3等旧编译器不支持64位整数类型,于是zlstdint也做了相应调整——若发现编译器不支持64位整数类型,便不会定义标准64位整数类型(int64_t、uint64_t、int_least64_t……)及相应宏(INT64_MAX、UINT64_MAX……),且intmax_t等最大整数类型被限制为32位。为了检测这种情况,zlstdint提供了Z_STDINT_INTMAX_BIT(intmax_t 类型的位数)宏。

  考虑到自动识别编译器的代码有可能会误判,于是提供了这些配置型宏——
Z_STDINT_H_USESYS: 是否使用的是编译器提供的 stdint.h .
Z_INTTYP_H_USESYS: 是否使用的是编译器提供的 inttypes.h .

三、测试结果

  测试过以下编译器——

* Virtual C++: 6, 7.1(2003), 8(2005), 9(2008), 10(2010), 11(2012), 12(2013).
* Turbo C++: Turbo C++ 3, Borland C++ 3.1, C++ Builder 6, C++ Builder XE3 .
* GCC(Linux): 4.7.0~4.8.2(Fedora 17~20), 4.6.3~4.8.2(Ubuntu 12.04~14.04).
* GCC(MinGW): 4.6.2(MinGW(20120426)), 4.7.1~4.9.2(TDM-GCC(MinGW-w64)).
* LLVM GCC: 4.2(Mac OS X Lion 10.7.4), 4.2.1(Mac OS X Mountain Lion 10.8.3).

  例如在DOS下的Turbo C++ 3中编译通过——

参考文献
~~~~~~~~

《ISO/IEC 9899:1999 (C99)》。ISO/IEC,1999。www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
《C99标准》。yourtommy。http://blog.csdn.net/yourtommy/article/details/7495033
《[C/C++] 显示各种C/C++编译器的预定义宏(C11标准、C++11标准、VC、BCB、Intel、GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/02/printmacro.html
《[C] 让VC、BCB支持C99的整数类型(stdint.h、inttypes.h)(兼容GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/08/c99int.html
《[C] 让VC支持C99的整数类型V1.01。避免包含目录问题,更名auto_stdint.h、auto_inttypes.h(在VC6至VC2012、GCC、BCB等编译器下测试通过)》. http://www.cnblogs.com/zyl910/archive/2013/01/10/c99int_v101.html
《[C] c99int(让VC等编译器自动兼容C99的整数类型)V1.02。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释》. http://www.cnblogs.com/zyl910/p/c99int_v102.html

源码下载——
https://github.com/zyl910/zlstdint

时间: 2024-10-29 19:10:12

[C] zlstdint(让VC、TC等编译器自动兼容C99的整数类型)V1.0。支持Turbo C++ 3等DOS下的编译器的相关文章

Visual C++ 编译器自动假定带 .C 扩展名的文件是 C 文件而不是 C++ 文件,并且拒绝 C++ 语法和关键字(c语言只能在大括号最前面申明变量)

今天在编译OpenGL红宝书附带源码中的light.c文件时遇到一个诡异的问题: 如图light .c,在不做任何修改的情况编译OK.然而只要在某些地方写了可执行代码,则会无法通过编译器编译! (这几行代码如果写在main函数里的第一句则OK) 我用的VS08.我把该文件发给其他朋友(用的VS10),同样也是这样的问题. 然而,我把文件名改成light.cpp后,问题解决了. 现在的问题是,代码文件按的后缀背后,会如何影响编辑器的编译呢? 可以做一个简单的测试: [cpp] view plain

条款6:如果不想使用编译器自动生成的函数,就应该明确的拒绝。

有些情况自己是不希望生成拷贝构造函数以及拷贝赋值运算符的,这种时候不能只是自己不去编写这些函数,因为这样编译器会自动的去生成这些函数.保险一点的做法是将拷贝构造函数以及拷贝赋值运算符都声明为private的.这样既阻止了编译器生成默认的版本,而且又阻止了别人去调用它. 注意上面的这条“将成员函数声明为private而故意的不去实现它”是一种常用手段,即使是标准程序库中有的部分也是这样做的. class HomeForSale//很明显,销售的两个方子一般内容都是不相同的,所以拷贝构造函数以及 {

Effective C++ 之 Item 6 : 若不想使用编译器自动生成的函数,就该明确拒绝

Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 6. 若不想使用编译器自动生成的函数,就该明确拒绝 (Explicitly disallow the use of compiler-generated functions you do not want) 地产中介商卖的是房子,一个中介软件系统自然而然想必有个 class 用来描述待售房屋: cla

Effective C++学习笔记 条款06:如不想使用编译器自动生成的函数,就该明确拒绝

一.为驳回编译器自动提供的机能,可将相应成员函数声明为private并且不予实现.(如果你仅仅是自己不实现的话,编译器会帮你实现) 如: class A { public: A(const string& name):m_name(name) {} private: //拒绝copy和赋值,声明为private,并且只声明不实现 A(const A&); A& operator=(const A&); private: string m_name; }; 二.对于拒绝赋值的

Effective C++ Item 6 若不想使用编译器自动生成的函数,就该明确拒绝

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现.使用像Uncopyable这样的base class也是一种方法 classUncopyable{ protected: //允许derived对象构造和析构 Uncopyable(){} ~Uncopyable(){} private: Uncopyable(constUncopyable&); //但阻止c

不使用编译器自动生成的拷贝构造函数和赋值运算符的方法

方法1:声明私有的拷贝构造函数和赋值运算符,这样不但阻止了编译器生成默认版本,并且使得用户无法调用他们,但是这时成员函数和友元函数还是可以调用他们,为了阻止他们的调用可以不定义这些私有的拷贝构造函数和赋值运算符.(标准库中也是如此阻止拷贝的) 代码段1.1:HomeForSale.h文件 #ifndef HOMEFORSALE_H #define HOMEFORSALE_H class CHomeForSale { public: CHomeForSale(){} private: CHomeF

C++、VC++、MFC网页自动注册、登陆、发帖、留言,QQ注册、QQ申请器源码、注册邮箱源码、自动发帖源码

C++.VC++.MFC网页自动注册.登陆.发帖.留言,QQ注册.QQ申请器源码.注册邮箱源码.自动发帖源码 参考资料: 自动登录yahoo邮箱http://blog.csdn.net/suisuibianbian/archive/2005/12/12/550260.aspx VC采集网页所有表单域http://blog.csdn.net/fjssharpsword/archive/2010/12/17/6081689.aspx 说说这类软件最常见的使用方式吧. 也许你经常看到有人发布了以下这类

【Effective c++】条款6:若不想使用编译器自动生成的函数就应该明确拒绝

地产中介卖的是房子,其使用的中介软件系统应该有个类用来描述卖掉的房子 class HomeFoeSale { ......} 但是任何房子都是独一无二的,不应该存在两个房子拥有同样的属性,因此以下操作不应该正确! HomeForSale h; HomeForSale h1(h); //调用复制构造函数 HomeForSale h2 = h; //调用赋值操作符 阻止这两个操作(复制.赋值)可以不声明它们,but自己不声明,编译器会自动生成,并且访问权限还是public.没办法只好声明出来,但是如

Effetive C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 通常如果你不希望class支持某一特定机能,只要不声明对应函数就是了.但这个策略对copy构造函数和copy assignment操作符却不起作用,你如果不声明它们,而某些人尝试调用它,编译器会为你声明它们. 这把你逼到了一个困境.如果你不声明copy构造函数和copy assignment操作符,编译器可能为你产出一份,于是你的clas支持copying.如果