关于stdint.h(uint16_t uint32_t)

2011-11-1

关于stdint.h(uint16_t uint32_t)


   stdint.h是c99中引进的一个标准C库的头文件.
   stdint.h中定义了一些整数类型,规则如下(其中N可以为8,16,32,64)
   intN_t, int_leastN_t, int_fastN_t表示长度为N位的整型数;
   uintN_t, uint_leastN_t, uint_fastN_t表示长度为N位的无符号整型数 ;
   stdint.h中的常量,定义以上各类型数的最大最小值(其中N可以为8,16,32,64)
   INTN_MIN, UINTN_MIN, INTN_MAX, UINTN_MAX ;
   INT_LEASEN_MIN, INT_LEASEN_MAX ;
   INT_FASTN_MIN, INT_FASTN_MAX ;


    分析stdint.h文件发现正如我们想象:uint16_t 可以是int也有可能是short,根据平台不同int可能是32位的也可能是16位的,而stdint.h是标准c库文件自然要考虑到所有情况,如:
	#if __STDINT_EXP(SHRT_MAX) == 0x7fff
	typedef signed short int16_t;
	typedef unsigned short uint16_t;
	#define __int16_t_defined 1
	#elif __STDINT_EXP(INT_MAX) == 0x7fff
	typedef signed int int16_t;
	typedef unsigned int uint16_t;
	#define __int16_t_defined 1
	#elif __STDINT_EXP(SCHAR_MAX) == 0x7fff
	typedef signed char int16_t;
	typedef unsigned char uint16_t;
	#define __int16_t_defined 1
	#endif
通过这段代码:
	#if defined(__GNUC__) && \
  		( (__GNUC__ >= 4) || \
    		( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2) ) )
	/* gcc > 3.2 implicitly defines the values we are interested */
	#define __STDINT_EXP(x) __##x##__
	#else
	#define __STDINT_EXP(x) x
	#include 
	#endif
得知如果是GNU编译器,其中__STDINT_EXP(SHRT_MAX)即是 __SHRT_MAX__宏。(ps:__GUNC__为gun编译器的主版本号,为编译器内建宏,即编译器版本大于3.2即使用#define __STDINT_EXP(x) __##x##__)
    由代码可见根据__SHRT_MAX__和__INT_MAX__及__SCHAR_MAX__的值将决定 uint16_t 使用shor 还是int或是char,而这三个宏的值是多少呢?如:__INT_MAX__ = ?,由我们自己定义吗?显然不是。不同编译器的编译规则已经决定了他的int、char、shor分别是几位的,所以__INT_MAX__的值应该由编译器定义,由用户定义的话就不合适了。__INT_MAX__是编译器的内建宏。不同的编译器都可以使用stdint.h,根据编译器自身的内建宏的不同实现:uint16_t int or short?
    关于__SHRT_MAX__为编译器内建宏的问题,我们可以做个测试:
void func (void)
{
    long long i = 0;
#ifdef __INT_MAX__
    i = __INT_MAX__;
#endif
    /*  输出i的值,或调试观察 */
}

关于数据类型长度是由编译器决定的:

如 int 是32位还是16位?由编译器决定,如果编译器选择的cpu不对应,那么编译出来的汇编将不能在目标cpu上运行。因为c语言中的变量定义实际上在汇编是不存在的,仅仅是对变量操作的时候转化成对地址的操作,所以编译器的不同或选项的不同编译出来的代码将是不同的

int i; i = 6553600;这个代码如果选择的是32位编译,那么汇编是对某个地址赋值,可是cpu是16位的,那么运行该汇编的时候必然是错误的。

如果选择16位编译,那么该语句将会被编译成两条汇编语句,分别是对两个连续地址进行高16位和低16位的赋值通过sizeof(int)即可知道当前编译器int是多少位的。

所以我们可以直接使用stdint.h里面的数据类型(不同的编译选项int的长度不同,stdint.h根据编译我们的编译选项编译器内建宏来判断,uint32_t对应int还是long long


附录:

stdint.h 来在Sourcery G++、WinARM、GNURX及newlib 为标准C库头文件。(有些编译器的stdint.h自己修改过,如瑞萨的rx编译器中的stdint.h)

 * Copyright (c) 2004, 2005 by
 * Ralf Corsepius, Ulm/Germany. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * is freely granted, provided that this notice is preserved.
 */


/*
 * @todo - Add support for wint_t types.
 */


#ifndef _STDINT_H
#define _STDINT_H


#ifdef __cplusplus
extern "C" {
#endif


#if defined(__GNUC__) && \
  ( (__GNUC__ >= 4) || \
    ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2) ) )
/* gcc > 3.2 implicitly defines the values we are interested */
#define __STDINT_EXP(x) __##x##__
#else
#define __STDINT_EXP(x) x
#include 
#endif


/* Check if "long long" is 64bit wide */
/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */
#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \
  || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) )
#define __have_longlong64 1
#endif


/* Check if "long" is 64bit or 32bit wide */
#if __STDINT_EXP(LONG_MAX) > 0x7fffffff
#define __have_long64 1
#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__)
#define __have_long32 1
#endif


#if __STDINT_EXP(SCHAR_MAX) == 0x7f
typedef signed char int8_t ;
typedef unsigned char uint8_t ;
#define __int8_t_defined 1
#endif


#if __int8_t_defined
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
#define __int_least8_t_defined 1
#endif


#if __STDINT_EXP(SHRT_MAX) == 0x7fff
typedef signed short int16_t;
typedef unsigned short uint16_t;
#define __int16_t_defined 1
#elif __STDINT_EXP(INT_MAX) == 0x7fff
typedef signed int int16_t;
typedef unsigned int uint16_t;
#define __int16_t_defined 1
#elif __STDINT_EXP(SCHAR_MAX) == 0x7fff
typedef signed char int16_t;
typedef unsigned char uint16_t;
#define __int16_t_defined 1
#endif


#if __int16_t_defined
typedef int16_t   	int_least16_t;
typedef uint16_t 	uint_least16_t;
#define __int_least16_t_defined 1


#if !__int_least8_t_defined
typedef int16_t	   	int_least8_t;
typedef uint16_t  	uint_least8_t;
#define __int_least8_t_defined 1
#endif
#endif


#if __have_long32
typedef signed long int32_t;
typedef unsigned long uint32_t;
#define __int32_t_defined 1
#elif __STDINT_EXP(INT_MAX) == 0x7fffffffL
typedef signed int int32_t;
typedef unsigned int uint32_t;
#define __int32_t_defined 1
#elif __STDINT_EXP(SHRT_MAX) == 0x7fffffffL
typedef signed short int32_t;
typedef unsigned short uint32_t;
#define __int32_t_defined 1
#elif __STDINT_EXP(SCHAR_MAX) == 0x7fffffffL
typedef signed char int32_t;
typedef unsigned char uint32_t;
#define __int32_t_defined 1
#endif


#if __int32_t_defined
typedef int32_t   	int_least32_t;
typedef uint32_t 	uint_least32_t;
#define __int_least32_t_defined 1


#if !__int_least8_t_defined
typedef int32_t	   	int_least8_t;
typedef uint32_t  	uint_least8_t;
#define __int_least8_t_defined 1
#endif


#if !__int_least16_t_defined
typedef int32_t	   	int_least16_t;
typedef uint32_t  	uint_least16_t;
#define __int_least16_t_defined 1
#endif
#endif


#if __have_long64
typedef signed long int64_t;
typedef unsigned long uint64_t;
#define __int64_t_defined 1
#elif __have_longlong64
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#define __int64_t_defined 1
#elif  __STDINT_EXP(INT_MAX) > 0x7fffffff
typedef signed int int64_t;
typedef unsigned int uint64_t;
#define __int64_t_defined 1
#endif


#if __int64_t_defined
typedef int64_t   	int_least64_t;
typedef uint64_t 	uint_least64_t;
#define __int_least64_t_defined 1


#if !__int_least8_t_defined
typedef int64_t	   	int_least8_t;
typedef uint64_t  	uint_least8_t;
#define __int_least8_t_defined 1
#endif


#if !__int_least16_t_defined
typedef int64_t	   	int_least16_t;
typedef uint64_t  	uint_least16_t;
#define __int_least16_t_defined 1
#endif


#if !__int_least32_t_defined
typedef int64_t	   	int_least32_t;
typedef uint64_t  	uint_least32_t;
#define __int_least32_t_defined 1
#endif
#endif


/*
 * Fastest minimum-width integer types
 *
 * Assume int to be the fastest type for all types with a width 
 * less than __INT_MAX__ rsp. INT_MAX
 */
#if __STDINT_EXP(INT_MAX) >= 0x7f
  typedef signed int int_fast8_t;
  typedef unsigned int uint_fast8_t;
#define __int_fast8_t_defined 1
#endif


#if __STDINT_EXP(INT_MAX) >= 0x7fff
  typedef signed int int_fast16_t;
  typedef unsigned int uint_fast16_t;
#define __int_fast16_t_defined 1
#endif


#if __STDINT_EXP(INT_MAX) >= 0x7fffffff
  typedef signed int int_fast32_t;
  typedef unsigned int uint_fast32_t;
#define __int_fast32_t_defined 1
#endif


#if __STDINT_EXP(INT_MAX) > 0x7fffffff
  typedef signed int int_fast64_t;
  typedef unsigned int uint_fast64_t;
#define __int_fast64_t_defined 1
#endif


/*
 * Fall back to [u]int_least_t for [u]int_fast_t types
 * not having been defined, yet.
 * Leave undefined, if [u]int_least_t should not be available.
 */
#if !__int_fast8_t_defined
#if __int_least8_t_defined
  typedef int_least8_t int_fast8_t;
  typedef uint_least8_t uint_fast8_t;
#define __int_fast8_t_defined 1
#endif
#endif


#if !__int_fast16_t_defined
#if __int_least16_t_defined
  typedef int_least16_t int_fast16_t;
  typedef uint_least16_t uint_fast16_t;
#define __int_fast16_t_defined 1
#endif
#endif


#if !__int_fast32_t_defined
#if __int_least32_t_defined
  typedef int_least32_t int_fast32_t;
  typedef uint_least32_t uint_fast32_t;
#define __int_fast32_t_defined 1
#endif
#endif


#if !__int_fast64_t_defined
#if __int_least64_t_defined
  typedef int_least64_t int_fast64_t;
  typedef uint_least64_t uint_fast64_t;
#define __int_fast64_t_defined 1
#endif
#endif


/* Greatest-width integer types */
/* Modern GCCs provide __INTMAX_TYPE__ */
#if defined(__INTMAX_TYPE__)
  typedef __INTMAX_TYPE__ intmax_t;
#elif __have_longlong64
  typedef signed long long intmax_t;
#else
  typedef signed long intmax_t;
#endif


/* Modern GCCs provide __UINTMAX_TYPE__ */
#if defined(__UINTMAX_TYPE__)
  typedef __UINTMAX_TYPE__ uintmax_t;
#elif __have_longlong64
  typedef unsigned long long uintmax_t;
#else
  typedef unsigned long uintmax_t;
#endif


/*
 * GCC doesn't provide an appropriate macro for [u]intptr_t
 * For now, use __PTRDIFF_TYPE__
 */
#if defined(__PTRDIFF_TYPE__)
typedef signed __PTRDIFF_TYPE__ intptr_t;
typedef unsigned __PTRDIFF_TYPE__ uintptr_t;
#else
/*
 * Fallback to hardcoded values, 
 * should be valid on cpu's with 32bit int/32bit void*
 */
typedef signed long intptr_t;
typedef unsigned long uintptr_t;
#endif


/* Limits of Specified-Width Integer Types */


#if __int8_t_defined
#define INT8_MIN 	-128
#define INT8_MAX 	 127
#define UINT8_MAX 	 255
#endif


#if __int_least8_t_defined
#define INT_LEAST8_MIN 	-128
#define INT_LEAST8_MAX 	 127
#define UINT_LEAST8_MAX	 255
#else
#error required type int_least8_t missing
#endif


#if __int16_t_defined
#define INT16_MIN 	-32768
#define INT16_MAX 	 32767
#define UINT16_MAX 	 65535
#endif


#if __int_least16_t_defined
#define INT_LEAST16_MIN	-32768
#define INT_LEAST16_MAX	 32767
#define UINT_LEAST16_MAX 65535
#else
#error required type int_least16_t missing
#endif


#if __int32_t_defined
#define INT32_MIN 	 (-2147483647-1)
#define INT32_MAX 	 2147483647
#define UINT32_MAX       4294967295U
#endif


#if __int_least32_t_defined
#define INT_LEAST32_MIN  (-2147483647-1)
#define INT_LEAST32_MAX  2147483647
#define UINT_LEAST32_MAX 4294967295U
#else
#error required type int_least32_t missing
#endif


#if __int64_t_defined
#if __have_long64
#define INT64_MIN 	(-9223372036854775807L-1L)
#define INT64_MAX 	 9223372036854775807L
#define UINT64_MAX 	18446744073709551615U
#elif __have_longlong64
#define INT64_MIN 	(-9223372036854775807LL-1LL)
#define INT64_MAX 	 9223372036854775807LL
#define UINT64_MAX 	18446744073709551615ULL
#endif
#endif


#if __int_least64_t_defined
#if __have_long64
#define INT_LEAST64_MIN  (-9223372036854775807L-1L)
#define INT_LEAST64_MAX  9223372036854775807L
#define UINT_LEAST64_MAX 18446744073709551615U
#elif __have_longlong64
#define INT_LEAST64_MIN  (-9223372036854775807LL-1LL)
#define INT_LEAST64_MAX  9223372036854775807LL
#define UINT_LEAST64_MAX 18446744073709551615ULL
#endif
#endif


#if __int_fast8_t_defined
#define INT_FAST8_MIN	INT8_MIN
#define INT_FAST8_MAX	INT8_MAX
#define UINT_FAST8_MAX	UINT8_MAX
#endif


#if __int_fast16_t_defined
#define INT_FAST16_MIN	INT16_MIN
#define INT_FAST16_MAX	INT16_MAX
#define UINT_FAST16_MAX	UINT16_MAX
#endif


#if __int_fast32_t_defined
#define INT_FAST32_MIN	INT32_MIN
#define INT_FAST32_MAX	INT32_MAX
#define UINT_FAST32_MAX	UINT32_MAX
#endif


#if __int_fast64_t_defined
#define INT_FAST64_MIN	INT64_MIN
#define INT_FAST64_MAX	INT64_MAX
#define UINT_FAST64_MAX	UINT64_MAX
#endif


/* This must match size_t in stddef.h, currently long unsigned int */
#define SIZE_MIN (-__STDINT_EXP(LONG_MAX) - 1L)
#define SIZE_MAX __STDINT_EXP(LONG_MAX)


/* This must match sig_atomic_t in  (currently int) */
#define SIG_ATOMIC_MIN (-__STDINT_EXP(INT_MAX) - 1)
#define SIG_ATOMIC_MAX __STDINT_EXP(INT_MAX)


/* This must match ptrdiff_t  in  (currently long int) */
#define PTRDIFF_MIN (-__STDINT_EXP(LONG_MAX) - 1L)
#define PTRDIFF_MAX __STDINT_EXP(LONG_MAX)


/** Macros for minimum-width integer constant expressions */
#define INT8_C(x)	x
#define UINT8_C(x)	x##U


#define INT16_C(x)	x
#define UINT16_C(x)	x##U


#if __have_long32
#define INT32_C(x)	x##L
#define UINT32_C(x)	x##UL
#else
#define INT32_C(x)	x
#define UINT32_C(x)	x##U
#endif


#if __int64_t_defined
#if __have_longlong64
#define INT64_C(x)	x##LL
#define UINT64_C(x)	x##ULL
#else
#define INT64_C(x)	x##L
#define UINT64_C(x)	x##UL
#endif
#endif


/** Macros for greatest-width integer constant expression */
#if __have_longlong64
#define INTMAX_C(x)	x##LL
#define UINTMAX_C(x)	x##ULL
#else
#define INTMAX_C(x)	x##L
#define UINTMAX_C(x)	x##UL
#endif




#ifdef __cplusplus
}
#endif


#endif /* _STDINT_H */


附录 stdint.h 来自mingw:

/* ISO C9x  7.18  Integer types 
 * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
 *
 *  THIS SOFTWARE IS NOT COPYRIGHTED
 *
 *  Contributor: Danny Smith 
 *
 *  This source code is offered for use in the public domain. You may
 *  use, modify or distribute it freely.
 *
 *  This code is distributed in the hope that it will be useful but
 *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
 *  DISCLAIMED. This includes but is not limited to warranties of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 *  Date: 2000-12-02
 */


#ifndef _STDINT_H
#define _STDINT_H
#define __need_wint_t
#define __need_wchar_t
#include 


/* 7.18.1.1  Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char   uint8_t;
typedef short  int16_t;
typedef unsigned short  uint16_t;
typedef int  int32_t;
typedef unsigned   uint32_t;
typedef long long  int64_t;
typedef unsigned long long   uint64_t;


/* 7.18.1.2  Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char   uint_least8_t;
typedef short  int_least16_t;
typedef unsigned short  uint_least16_t;
typedef int  int_least32_t;
typedef unsigned   uint_least32_t;
typedef long long  int_least64_t;
typedef unsigned long long   uint_least64_t;


/*  7.18.1.3  Fastest minimum-width integer types 
 *  Not actually guaranteed to be fastest for all purposes
 *  Here we use the exact-width types for 8 and 16-bit ints. 
 */
typedef signed char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short  int_fast16_t;
typedef unsigned short  uint_fast16_t;
typedef int  int_fast32_t;
typedef unsigned  int  uint_fast32_t;
typedef long long  int_fast64_t;
typedef unsigned long long   uint_fast64_t;


/* 7.18.1.4  Integer types capable of holding object pointers */


#ifndef _INTPTR_T_DEFINED
#define _INTPTR_T_DEFINED
#ifdef _WIN64
  typedef __int64 intptr_t;
#else
  typedef int intptr_t;
#endif
#endif


#ifndef _UINTPTR_T_DEFINED
#define _UINTPTR_T_DEFINED
#ifdef _WIN64
  typedef unsigned __int64 uintptr_t;
#else
  typedef unsigned int uintptr_t;
#endif
#endif


/* 7.18.1.5  Greatest-width integer types */
typedef long long  intmax_t;
typedef unsigned long long uintmax_t;


/* 7.18.2  Limits of specified-width integer types */
#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS)


/* 7.18.2.1  Limits of exact-width integer types */
#define INT8_MIN (-128) 
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN  (-9223372036854775807LL - 1)


#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL


#define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff  /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */


/* 7.18.2.2  Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN


#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX


#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX


/* 7.18.2.3  Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN


#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX


#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX


/* 7.18.2.4  Limits of integer types capable of holding
    object pointers */
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif


/* 7.18.2.5  Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX


/* 7.18.3  Limits of other integer types */
#define PTRDIFF_MIN INTPTR_MIN
#define PTRDIFF_MAX INTPTR_MAX


#define SIG_ATOMIC_MIN INTPTR_MIN
#define SIG_ATOMIC_MAX INTPTR_MAX


#define SIZE_MAX UINTPTR_MAX


#ifndef WCHAR_MIN  /* also in wchar.h */ 
#define WCHAR_MIN 0
#define WCHAR_MAX 0xffff /* UINT16_MAX */
#endif


/*
 * wint_t is unsigned short for compatibility with MS runtime
 */
#define WINT_MIN 0
#define WINT_MAX 0xffff /* UINT16_MAX */


#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */




/* 7.18.4  Macros for integer constants */
#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS)


/* 7.18.4.1  Macros for minimum-width integer constants


    Accoding to Douglas Gwyn :
	"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
	9899:1999 as initially published, the expansion was required
	to be an integer constant of precisely matching type, which
	is impossible to accomplish for the shorter types on most
	platforms, because C99 provides no standard way to designate
	an integer constant with width less than that of type int.
	TC1 changed this to require just an integer constant
	*expression* with *promoted* type."
*/


#define INT8_C(val) val
#define UINT8_C(val) val
#define INT16_C(val) val
#define UINT16_C(val) val


#define INT32_C(val) val
#define UINT32_C(val) val##U
#define INT64_C(val) val##LL
#define UINT64_C(val) val##ULL


/* 7.18.4.2  Macros for greatest-width integer constants */
#define INTMAX_C(val)  INT64_C(val)
#define UINTMAX_C(val) UINT64_C(val)


#endif  /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */




你可能感兴趣的:(技术)