2011-11-1
关于stdint.h(uint16_t uint32_t)
#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 <limits.h> #endif得知如果是GNU编译器,其中__STDINT_EXP(SHRT_MAX)即是 __SHRT_MAX__宏。(ps:__GUNC__为gun编译器的主版本号,为编译器内建宏,即编译器版本大于3.2即使用#define __STDINT_EXP(x) __##x##__)
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 <limits.h> #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<N>_t for [u]int_fast<N>_t types * not having been defined, yet. * Leave undefined, if [u]int_least<N>_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 <signal.h> (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 <stddef.h> (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 <stdint.h> * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794) * * THIS SOFTWARE IS NOT COPYRIGHTED * * Contributor: Danny Smith <[email protected]> * * 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 <stddef.h> /* 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 <[email protected]>: "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 */