找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 8301|回复: 3

【C语言】给微软MSVC使用的inttypes.h和stdatomic.h

[复制链接]
发表于 2019-2-3 11:50:49 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
MSVC一直以来对C语言标准支持不全,但有时候又具备一些奇怪的(对于当年而言的)超前特性(比如匿名联合体和结构体等)使其依然具有一定的实用性。即便如此,你要想让代码写得舒服,你还是得按照标准来写。

那么对于最基础的整数类型,我们是使用MSVC里面能用的stdint.h好呢,还是用C99标准新添加的inttypes.h好呢?虽说后者增加的东西或许并不都是你需要的,比如对printf格式代码的跨平台支持,以及完整除法运算所需的imaxdiv_t类型和imaxdiv函数等。

此外,当你尝到了GCC的全程序优化的甜头后,你再跑回去看MSVC,你会怎么想呢?
  • C标准支持不全。局部变量甚至必须被定义在语句的前面。
  • 没有足够强大的全程序优化,虽说有/LTCG,但它看起来就和没有一样。
  • 对SIMD指令集的优化贼弱,强行给你擅自加入一堆movaps等,来解决由于它自身优化很差而带来的寄存器不够的问题。

以及
  • 完善的代码高亮和自动提示、自动补全功能。
    (虽说对于C语言调用COM类的状况下而言,它的自动提示功能并不知道你写的是C还是C++,会在你试图通过虚表调用COM类的时候告诉你“没有lpVtbl成员”)
  • 令人上瘾的F12转到定义功能。这个功能不仅仅对于编程开发,对于编程的学习而言更具有关键性的使用价值。
  • 虽说不完整,但基本够用的一整套支持多线程和多机器的调试器工具。
  • 漂亮的界面
  • 一帮惹不起的信徒(咳咳)

由于Cygwin过于Tony带水,拖家带口,有悖于我们希望编译器足够好用的初衷,我选择MinGW。
然而我发现我在使用MinGW的时候我的代码里既可以使用Windows.h(需要设置-mwindows编译器命令行参数)又可以使用inttypes.h和stdatomic.h。我甚至还可以使用pthread.h,虽说其实根本不好用——它依赖unistd.h,但这样一来,我搞不好就要把Unix全家桶搬到Windows里面了,这十分南辕北辙。不如直接用Windows的API。

对于如此纠结的情况,我是使用stdint.h好呢,还是使用inttypes.h好呢,我该不该使用stdatomic.h呢?

我决定采用打补丁的方式,对于缺乏这些头文件的情况下,使用替补的去代替。我在我的工程目录里添加两个目录,一个是“备用头文件”,用于存放这些备用的头文件。另一个则是“额外包含头文件”,这个是给编译器查找头文件目录指定的,让编译器从这里面查找额外的头文件。任何人如果想要编译我这个工程,他应该先用自己的工具编译一下。如果编译不通过,他会在我的文档里看到说明,然后把缺失的头文件从“备用头文件”目录里拷贝到“额外包含头文件”目录里,然后再次编译即可。

那么问题来了。这两个头文件我是应该自己写呢,还是从现有的找呢?

人生宝贵,造重复轮子(还不一定比别人的圆)不可取。我决定使用别人写好的头文件。

其中,谷歌的开源库里有inttypes.h是给MSVC用的。
https://code.google.com/archive/p/msinttypes/downloads
此处我直接搬运一下:
it.png
msinttypes-r26.zip (6.74 KB, 下载次数: 2)
我搬运的是我在写这篇帖子的时候看到的最新的版本。它是有可能更新的,所以请从原网址查看为妙。

它里面其实同时包含了stdint.h和inttypes.h。
目测是为了防止不同MSVC的stdint.h版本不同而带来的问题。

然后,我从FFMpeg的开源库里找到了给MSVC用的stdatomic.h
https://www.ffmpeg.org/doxygen/t ... omic_8h_source.html
https://github.com/FFmpeg/FFmpeg ... s/win32/stdatomic.h
ffmpeg的更新是十分频繁的。建议自己上它的网站去看。
此处依然搬运一下:
stdatomic.zip (1.43 KB, 下载次数: 7)

也不长,我就直接复制到帖子里了。可以看出,stdatomic原有的内存顺序部分的特性被丢了个精光,全都变成了最严格的原子操作方式:memory_order_seq_cst。
我们其实并不应该给stdatomic的行为擅自加料,考虑到Windows运行在各种不同的平台上,还是以严格为好。典型例子,牙膏厂Atom系列CPU和NUMA架构多处理器Xeon对于原子操作的严格性要求就不一样,而且它们的实际行为也大不一样——Atom更多是对自己内部的缓存进行原子操作,而Xeon则更多是强制读写内存,如果你在NUMA架构上让Xeon不强制读写内存的话,两个处理器之间的内存同步性就会丢失。
stdatomic.h
  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */

  18. #ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H
  19. #define COMPAT_ATOMICS_WIN32_STDATOMIC_H

  20. #define WIN32_LEAN_AND_MEAN
  21. #include <stddef.h>
  22. #include <stdint.h>
  23. #include <windows.h>

  24. #define ATOMIC_FLAG_INIT 0

  25. #define ATOMIC_VAR_INIT(value) (value)

  26. #define atomic_init(obj, value) \
  27. do {                            \
  28.     *(obj) = (value);           \
  29. } while(0)

  30. #define kill_dependency(y) ((void)0)

  31. #define atomic_thread_fence(order) \
  32.     MemoryBarrier();

  33. #define atomic_signal_fence(order) \
  34.     ((void)0)

  35. #define atomic_is_lock_free(obj) 0

  36. typedef intptr_t atomic_flag;
  37. typedef intptr_t atomic_bool;
  38. typedef intptr_t atomic_char;
  39. typedef intptr_t atomic_schar;
  40. typedef intptr_t atomic_uchar;
  41. typedef intptr_t atomic_short;
  42. typedef intptr_t atomic_ushort;
  43. typedef intptr_t atomic_int;
  44. typedef intptr_t atomic_uint;
  45. typedef intptr_t atomic_long;
  46. typedef intptr_t atomic_ulong;
  47. typedef intptr_t atomic_llong;
  48. typedef intptr_t atomic_ullong;
  49. typedef intptr_t atomic_wchar_t;
  50. typedef intptr_t atomic_int_least8_t;
  51. typedef intptr_t atomic_uint_least8_t;
  52. typedef intptr_t atomic_int_least16_t;
  53. typedef intptr_t atomic_uint_least16_t;
  54. typedef intptr_t atomic_int_least32_t;
  55. typedef intptr_t atomic_uint_least32_t;
  56. typedef intptr_t atomic_int_least64_t;
  57. typedef intptr_t atomic_uint_least64_t;
  58. typedef intptr_t atomic_int_fast8_t;
  59. typedef intptr_t atomic_uint_fast8_t;
  60. typedef intptr_t atomic_int_fast16_t;
  61. typedef intptr_t atomic_uint_fast16_t;
  62. typedef intptr_t atomic_int_fast32_t;
  63. typedef intptr_t atomic_uint_fast32_t;
  64. typedef intptr_t atomic_int_fast64_t;
  65. typedef intptr_t atomic_uint_fast64_t;
  66. typedef intptr_t atomic_intptr_t;
  67. typedef intptr_t atomic_uintptr_t;
  68. typedef intptr_t atomic_size_t;
  69. typedef intptr_t atomic_ptrdiff_t;
  70. typedef intptr_t atomic_intmax_t;
  71. typedef intptr_t atomic_uintmax_t;

  72. #define atomic_store(object, desired)   \
  73. do {                                    \
  74.     *(object) = (desired);              \
  75.     MemoryBarrier();                    \
  76. } while (0)

  77. #define atomic_store_explicit(object, desired, order) \
  78.     atomic_store(object, desired)

  79. #define atomic_load(object) \
  80.     (MemoryBarrier(), *(object))

  81. #define atomic_load_explicit(object, order) \
  82.     atomic_load(object)

  83. #define atomic_exchange(object, desired) \
  84.     InterlockedExchangePointer(object, desired);

  85. #define atomic_exchange_explicit(object, desired, order) \
  86.     atomic_exchange(object, desired)

  87. static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
  88.                                                  intptr_t desired)
  89. {
  90.     intptr_t old = *expected;
  91.     *expected = (intptr_t)InterlockedCompareExchangePointer(
  92.         (PVOID *)object, (PVOID)desired, (PVOID)old);
  93.     return *expected == old;
  94. }

  95. #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
  96.     atomic_compare_exchange_strong(object, expected, desired)

  97. #define atomic_compare_exchange_weak(object, expected, desired) \
  98.     atomic_compare_exchange_strong(object, expected, desired)

  99. #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
  100.     atomic_compare_exchange_weak(object, expected, desired)

  101. #ifdef _WIN64
  102. #define atomic_fetch_add(object, operand) \
  103.     InterlockedExchangeAdd64(object, operand)

  104. #define atomic_fetch_sub(object, operand) \
  105.     InterlockedExchangeAdd64(object, -(operand))

  106. #define atomic_fetch_or(object, operand) \
  107.     InterlockedOr64(object, operand)

  108. #define atomic_fetch_xor(object, operand) \
  109.     InterlockedXor64(object, operand)

  110. #define atomic_fetch_and(object, operand) \
  111.     InterlockedAnd64(object, operand)
  112. #else
  113. #define atomic_fetch_add(object, operand) \
  114.     InterlockedExchangeAdd(object, operand)

  115. #define atomic_fetch_sub(object, operand) \
  116.     InterlockedExchangeAdd(object, -(operand))

  117. #define atomic_fetch_or(object, operand) \
  118.     InterlockedOr(object, operand)

  119. #define atomic_fetch_xor(object, operand) \
  120.     InterlockedXor(object, operand)

  121. #define atomic_fetch_and(object, operand) \
  122.     InterlockedAnd(object, operand)
  123. #endif /* _WIN64 */

  124. #define atomic_fetch_add_explicit(object, operand, order) \
  125.     atomic_fetch_add(object, operand)

  126. #define atomic_fetch_sub_explicit(object, operand, order) \
  127.     atomic_fetch_sub(object, operand)

  128. #define atomic_fetch_or_explicit(object, operand, order) \
  129.     atomic_fetch_or(object, operand)

  130. #define atomic_fetch_xor_explicit(object, operand, order) \
  131.     atomic_fetch_xor(object, operand)

  132. #define atomic_fetch_and_explicit(object, operand, order) \
  133.     atomic_fetch_and(object, operand)

  134. #define atomic_flag_test_and_set(object) \
  135.     atomic_exchange(object, 1)

  136. #define atomic_flag_test_and_set_explicit(object, order) \
  137.     atomic_flag_test_and_set(object)

  138. #define atomic_flag_clear(object) \
  139.     atomic_store(object, 0)

  140. #define atomic_flag_clear_explicit(object, order) \
  141.     atomic_flag_clear(object)

  142. #endif /* COMPAT_ATOMICS_WIN32_STDATOMIC_H */
复制代码
顺带我也把之前提到的inttypes.h也直接丢帖子里,便于Ctrl+C Ctrl+V。
inttypes.h
  1. // ISO C9x  compliant inttypes.h for Microsoft Visual Studio
  2. // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
  3. //
  4. //  Copyright (c) 2006 Alexander Chemeris
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. //   1. Redistributions of source code must retain the above copyright notice,
  10. //      this list of conditions and the following disclaimer.
  11. //
  12. //   2. Redistributions in binary form must reproduce the above copyright
  13. //      notice, this list of conditions and the following disclaimer in the
  14. //      documentation and/or other materials provided with the distribution.
  15. //
  16. //   3. The name of the author may be used to endorse or promote products
  17. //      derived from this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25. // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27. // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28. // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. //
  30. ///////////////////////////////////////////////////////////////////////////////

  31. #ifndef _MSC_VER // [
  32. #error "Use this header only with Microsoft Visual C++ compilers!"
  33. #endif // _MSC_VER ]

  34. #ifndef _MSC_INTTYPES_H_ // [
  35. #define _MSC_INTTYPES_H_

  36. #if _MSC_VER > 1000
  37. #pragma once
  38. #endif

  39. #include "stdint.h"

  40. // 7.8 Format conversion of integer types

  41. typedef struct {
  42.    intmax_t quot;
  43.    intmax_t rem;
  44. } imaxdiv_t;

  45. // 7.8.1 Macros for format specifiers

  46. #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198

  47. // The fprintf macros for signed integers are:
  48. #define PRId8       "d"
  49. #define PRIi8       "i"
  50. #define PRIdLEAST8  "d"
  51. #define PRIiLEAST8  "i"
  52. #define PRIdFAST8   "d"
  53. #define PRIiFAST8   "i"

  54. #define PRId16       "hd"
  55. #define PRIi16       "hi"
  56. #define PRIdLEAST16  "hd"
  57. #define PRIiLEAST16  "hi"
  58. #define PRIdFAST16   "hd"
  59. #define PRIiFAST16   "hi"

  60. #define PRId32       "I32d"
  61. #define PRIi32       "I32i"
  62. #define PRIdLEAST32  "I32d"
  63. #define PRIiLEAST32  "I32i"
  64. #define PRIdFAST32   "I32d"
  65. #define PRIiFAST32   "I32i"

  66. #define PRId64       "I64d"
  67. #define PRIi64       "I64i"
  68. #define PRIdLEAST64  "I64d"
  69. #define PRIiLEAST64  "I64i"
  70. #define PRIdFAST64   "I64d"
  71. #define PRIiFAST64   "I64i"

  72. #define PRIdMAX     "I64d"
  73. #define PRIiMAX     "I64i"

  74. #define PRIdPTR     "Id"
  75. #define PRIiPTR     "Ii"

  76. // The fprintf macros for unsigned integers are:
  77. #define PRIo8       "o"
  78. #define PRIu8       "u"
  79. #define PRIx8       "x"
  80. #define PRIX8       "X"
  81. #define PRIoLEAST8  "o"
  82. #define PRIuLEAST8  "u"
  83. #define PRIxLEAST8  "x"
  84. #define PRIXLEAST8  "X"
  85. #define PRIoFAST8   "o"
  86. #define PRIuFAST8   "u"
  87. #define PRIxFAST8   "x"
  88. #define PRIXFAST8   "X"

  89. #define PRIo16       "ho"
  90. #define PRIu16       "hu"
  91. #define PRIx16       "hx"
  92. #define PRIX16       "hX"
  93. #define PRIoLEAST16  "ho"
  94. #define PRIuLEAST16  "hu"
  95. #define PRIxLEAST16  "hx"
  96. #define PRIXLEAST16  "hX"
  97. #define PRIoFAST16   "ho"
  98. #define PRIuFAST16   "hu"
  99. #define PRIxFAST16   "hx"
  100. #define PRIXFAST16   "hX"

  101. #define PRIo32       "I32o"
  102. #define PRIu32       "I32u"
  103. #define PRIx32       "I32x"
  104. #define PRIX32       "I32X"
  105. #define PRIoLEAST32  "I32o"
  106. #define PRIuLEAST32  "I32u"
  107. #define PRIxLEAST32  "I32x"
  108. #define PRIXLEAST32  "I32X"
  109. #define PRIoFAST32   "I32o"
  110. #define PRIuFAST32   "I32u"
  111. #define PRIxFAST32   "I32x"
  112. #define PRIXFAST32   "I32X"

  113. #define PRIo64       "I64o"
  114. #define PRIu64       "I64u"
  115. #define PRIx64       "I64x"
  116. #define PRIX64       "I64X"
  117. #define PRIoLEAST64  "I64o"
  118. #define PRIuLEAST64  "I64u"
  119. #define PRIxLEAST64  "I64x"
  120. #define PRIXLEAST64  "I64X"
  121. #define PRIoFAST64   "I64o"
  122. #define PRIuFAST64   "I64u"
  123. #define PRIxFAST64   "I64x"
  124. #define PRIXFAST64   "I64X"

  125. #define PRIoMAX     "I64o"
  126. #define PRIuMAX     "I64u"
  127. #define PRIxMAX     "I64x"
  128. #define PRIXMAX     "I64X"

  129. #define PRIoPTR     "Io"
  130. #define PRIuPTR     "Iu"
  131. #define PRIxPTR     "Ix"
  132. #define PRIXPTR     "IX"

  133. // The fscanf macros for signed integers are:
  134. #define SCNd8       "d"
  135. #define SCNi8       "i"
  136. #define SCNdLEAST8  "d"
  137. #define SCNiLEAST8  "i"
  138. #define SCNdFAST8   "d"
  139. #define SCNiFAST8   "i"

  140. #define SCNd16       "hd"
  141. #define SCNi16       "hi"
  142. #define SCNdLEAST16  "hd"
  143. #define SCNiLEAST16  "hi"
  144. #define SCNdFAST16   "hd"
  145. #define SCNiFAST16   "hi"

  146. #define SCNd32       "ld"
  147. #define SCNi32       "li"
  148. #define SCNdLEAST32  "ld"
  149. #define SCNiLEAST32  "li"
  150. #define SCNdFAST32   "ld"
  151. #define SCNiFAST32   "li"

  152. #define SCNd64       "I64d"
  153. #define SCNi64       "I64i"
  154. #define SCNdLEAST64  "I64d"
  155. #define SCNiLEAST64  "I64i"
  156. #define SCNdFAST64   "I64d"
  157. #define SCNiFAST64   "I64i"

  158. #define SCNdMAX     "I64d"
  159. #define SCNiMAX     "I64i"

  160. #ifdef _WIN64 // [
  161. #  define SCNdPTR     "I64d"
  162. #  define SCNiPTR     "I64i"
  163. #else  // _WIN64 ][
  164. #  define SCNdPTR     "ld"
  165. #  define SCNiPTR     "li"
  166. #endif  // _WIN64 ]

  167. // The fscanf macros for unsigned integers are:
  168. #define SCNo8       "o"
  169. #define SCNu8       "u"
  170. #define SCNx8       "x"
  171. #define SCNX8       "X"
  172. #define SCNoLEAST8  "o"
  173. #define SCNuLEAST8  "u"
  174. #define SCNxLEAST8  "x"
  175. #define SCNXLEAST8  "X"
  176. #define SCNoFAST8   "o"
  177. #define SCNuFAST8   "u"
  178. #define SCNxFAST8   "x"
  179. #define SCNXFAST8   "X"

  180. #define SCNo16       "ho"
  181. #define SCNu16       "hu"
  182. #define SCNx16       "hx"
  183. #define SCNX16       "hX"
  184. #define SCNoLEAST16  "ho"
  185. #define SCNuLEAST16  "hu"
  186. #define SCNxLEAST16  "hx"
  187. #define SCNXLEAST16  "hX"
  188. #define SCNoFAST16   "ho"
  189. #define SCNuFAST16   "hu"
  190. #define SCNxFAST16   "hx"
  191. #define SCNXFAST16   "hX"

  192. #define SCNo32       "lo"
  193. #define SCNu32       "lu"
  194. #define SCNx32       "lx"
  195. #define SCNX32       "lX"
  196. #define SCNoLEAST32  "lo"
  197. #define SCNuLEAST32  "lu"
  198. #define SCNxLEAST32  "lx"
  199. #define SCNXLEAST32  "lX"
  200. #define SCNoFAST32   "lo"
  201. #define SCNuFAST32   "lu"
  202. #define SCNxFAST32   "lx"
  203. #define SCNXFAST32   "lX"

  204. #define SCNo64       "I64o"
  205. #define SCNu64       "I64u"
  206. #define SCNx64       "I64x"
  207. #define SCNX64       "I64X"
  208. #define SCNoLEAST64  "I64o"
  209. #define SCNuLEAST64  "I64u"
  210. #define SCNxLEAST64  "I64x"
  211. #define SCNXLEAST64  "I64X"
  212. #define SCNoFAST64   "I64o"
  213. #define SCNuFAST64   "I64u"
  214. #define SCNxFAST64   "I64x"
  215. #define SCNXFAST64   "I64X"

  216. #define SCNoMAX     "I64o"
  217. #define SCNuMAX     "I64u"
  218. #define SCNxMAX     "I64x"
  219. #define SCNXMAX     "I64X"

  220. #ifdef _WIN64 // [
  221. #  define SCNoPTR     "I64o"
  222. #  define SCNuPTR     "I64u"
  223. #  define SCNxPTR     "I64x"
  224. #  define SCNXPTR     "I64X"
  225. #else  // _WIN64 ][
  226. #  define SCNoPTR     "lo"
  227. #  define SCNuPTR     "lu"
  228. #  define SCNxPTR     "lx"
  229. #  define SCNXPTR     "lX"
  230. #endif  // _WIN64 ]

  231. #endif // __STDC_FORMAT_MACROS ]

  232. // 7.8.2 Functions for greatest-width integer types

  233. // 7.8.2.1 The imaxabs function
  234. #define imaxabs _abs64

  235. // 7.8.2.2 The imaxdiv function

  236. // This is modified version of div() function from Microsoft's div.c found
  237. // in %MSVC.NET%\crt\src\div.c
  238. #ifdef STATIC_IMAXDIV // [
  239. static
  240. #else // STATIC_IMAXDIV ][
  241. _inline
  242. #endif // STATIC_IMAXDIV ]
  243. imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
  244. {
  245.    imaxdiv_t result;

  246.    result.quot = numer / denom;
  247.    result.rem = numer % denom;

  248.    if (numer < 0 && result.rem > 0) {
  249.       // did division wrong; must fix up
  250.       ++result.quot;
  251.       result.rem -= denom;
  252.    }

  253.    return result;
  254. }

  255. // 7.8.2.3 The strtoimax and strtoumax functions
  256. #define strtoimax _strtoi64
  257. #define strtoumax _strtoui64

  258. // 7.8.2.4 The wcstoimax and wcstoumax functions
  259. #define wcstoimax _wcstoi64
  260. #define wcstoumax _wcstoui64


  261. #endif // _MSC_INTTYPES_H_ ]
复制代码
还有它所依赖的stdint.h
stdint.h
  1. // ISO C9x  compliant stdint.h for Microsoft Visual Studio
  2. // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
  3. //
  4. //  Copyright (c) 2006-2008 Alexander Chemeris
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. //   1. Redistributions of source code must retain the above copyright notice,
  10. //      this list of conditions and the following disclaimer.
  11. //
  12. //   2. Redistributions in binary form must reproduce the above copyright
  13. //      notice, this list of conditions and the following disclaimer in the
  14. //      documentation and/or other materials provided with the distribution.
  15. //
  16. //   3. The name of the author may be used to endorse or promote products
  17. //      derived from this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  25. // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  26. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  27. // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  28. // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. //
  30. ///////////////////////////////////////////////////////////////////////////////

  31. #ifndef _MSC_VER // [
  32. #error "Use this header only with Microsoft Visual C++ compilers!"
  33. #endif // _MSC_VER ]

  34. #ifndef _MSC_STDINT_H_ // [
  35. #define _MSC_STDINT_H_

  36. #if _MSC_VER > 1000
  37. #pragma once
  38. #endif

  39. #include <limits.h>

  40. // For Visual Studio 6 in C++ mode and for many Visual Studio versions when
  41. // compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
  42. // or compiler give many errors like this:
  43. //   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
  44. #ifdef __cplusplus
  45. extern "C" {
  46. #endif
  47. #  include <wchar.h>
  48. #ifdef __cplusplus
  49. }
  50. #endif

  51. // Define _W64 macros to mark types changing their size, like intptr_t.
  52. #ifndef _W64
  53. #  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
  54. #     define _W64 __w64
  55. #  else
  56. #     define _W64
  57. #  endif
  58. #endif


  59. // 7.18.1 Integer types

  60. // 7.18.1.1 Exact-width integer types

  61. // Visual Studio 6 and Embedded Visual C++ 4 doesn't
  62. // realize that, e.g. char has the same size as __int8
  63. // so we give up on __intX for them.
  64. #if (_MSC_VER < 1300)
  65.    typedef signed char       int8_t;
  66.    typedef signed short      int16_t;
  67.    typedef signed int        int32_t;
  68.    typedef unsigned char     uint8_t;
  69.    typedef unsigned short    uint16_t;
  70.    typedef unsigned int      uint32_t;
  71. #else
  72.    typedef signed __int8     int8_t;
  73.    typedef signed __int16    int16_t;
  74.    typedef signed __int32    int32_t;
  75.    typedef unsigned __int8   uint8_t;
  76.    typedef unsigned __int16  uint16_t;
  77.    typedef unsigned __int32  uint32_t;
  78. #endif
  79. typedef signed __int64       int64_t;
  80. typedef unsigned __int64     uint64_t;


  81. // 7.18.1.2 Minimum-width integer types
  82. typedef int8_t    int_least8_t;
  83. typedef int16_t   int_least16_t;
  84. typedef int32_t   int_least32_t;
  85. typedef int64_t   int_least64_t;
  86. typedef uint8_t   uint_least8_t;
  87. typedef uint16_t  uint_least16_t;
  88. typedef uint32_t  uint_least32_t;
  89. typedef uint64_t  uint_least64_t;

  90. // 7.18.1.3 Fastest minimum-width integer types
  91. typedef int8_t    int_fast8_t;
  92. typedef int16_t   int_fast16_t;
  93. typedef int32_t   int_fast32_t;
  94. typedef int64_t   int_fast64_t;
  95. typedef uint8_t   uint_fast8_t;
  96. typedef uint16_t  uint_fast16_t;
  97. typedef uint32_t  uint_fast32_t;
  98. typedef uint64_t  uint_fast64_t;

  99. // 7.18.1.4 Integer types capable of holding object pointers
  100. #ifdef _WIN64 // [
  101.    typedef signed __int64    intptr_t;
  102.    typedef unsigned __int64  uintptr_t;
  103. #else // _WIN64 ][
  104.    typedef _W64 signed int   intptr_t;
  105.    typedef _W64 unsigned int uintptr_t;
  106. #endif // _WIN64 ]

  107. // 7.18.1.5 Greatest-width integer types
  108. typedef int64_t   intmax_t;
  109. typedef uint64_t  uintmax_t;


  110. // 7.18.2 Limits of specified-width integer types

  111. #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259

  112. // 7.18.2.1 Limits of exact-width integer types
  113. #define INT8_MIN     ((int8_t)_I8_MIN)
  114. #define INT8_MAX     _I8_MAX
  115. #define INT16_MIN    ((int16_t)_I16_MIN)
  116. #define INT16_MAX    _I16_MAX
  117. #define INT32_MIN    ((int32_t)_I32_MIN)
  118. #define INT32_MAX    _I32_MAX
  119. #define INT64_MIN    ((int64_t)_I64_MIN)
  120. #define INT64_MAX    _I64_MAX
  121. #define UINT8_MAX    _UI8_MAX
  122. #define UINT16_MAX   _UI16_MAX
  123. #define UINT32_MAX   _UI32_MAX
  124. #define UINT64_MAX   _UI64_MAX

  125. // 7.18.2.2 Limits of minimum-width integer types
  126. #define INT_LEAST8_MIN    INT8_MIN
  127. #define INT_LEAST8_MAX    INT8_MAX
  128. #define INT_LEAST16_MIN   INT16_MIN
  129. #define INT_LEAST16_MAX   INT16_MAX
  130. #define INT_LEAST32_MIN   INT32_MIN
  131. #define INT_LEAST32_MAX   INT32_MAX
  132. #define INT_LEAST64_MIN   INT64_MIN
  133. #define INT_LEAST64_MAX   INT64_MAX
  134. #define UINT_LEAST8_MAX   UINT8_MAX
  135. #define UINT_LEAST16_MAX  UINT16_MAX
  136. #define UINT_LEAST32_MAX  UINT32_MAX
  137. #define UINT_LEAST64_MAX  UINT64_MAX

  138. // 7.18.2.3 Limits of fastest minimum-width integer types
  139. #define INT_FAST8_MIN    INT8_MIN
  140. #define INT_FAST8_MAX    INT8_MAX
  141. #define INT_FAST16_MIN   INT16_MIN
  142. #define INT_FAST16_MAX   INT16_MAX
  143. #define INT_FAST32_MIN   INT32_MIN
  144. #define INT_FAST32_MAX   INT32_MAX
  145. #define INT_FAST64_MIN   INT64_MIN
  146. #define INT_FAST64_MAX   INT64_MAX
  147. #define UINT_FAST8_MAX   UINT8_MAX
  148. #define UINT_FAST16_MAX  UINT16_MAX
  149. #define UINT_FAST32_MAX  UINT32_MAX
  150. #define UINT_FAST64_MAX  UINT64_MAX

  151. // 7.18.2.4 Limits of integer types capable of holding object pointers
  152. #ifdef _WIN64 // [
  153. #  define INTPTR_MIN   INT64_MIN
  154. #  define INTPTR_MAX   INT64_MAX
  155. #  define UINTPTR_MAX  UINT64_MAX
  156. #else // _WIN64 ][
  157. #  define INTPTR_MIN   INT32_MIN
  158. #  define INTPTR_MAX   INT32_MAX
  159. #  define UINTPTR_MAX  UINT32_MAX
  160. #endif // _WIN64 ]

  161. // 7.18.2.5 Limits of greatest-width integer types
  162. #define INTMAX_MIN   INT64_MIN
  163. #define INTMAX_MAX   INT64_MAX
  164. #define UINTMAX_MAX  UINT64_MAX

  165. // 7.18.3 Limits of other integer types

  166. #ifdef _WIN64 // [
  167. #  define PTRDIFF_MIN  _I64_MIN
  168. #  define PTRDIFF_MAX  _I64_MAX
  169. #else  // _WIN64 ][
  170. #  define PTRDIFF_MIN  _I32_MIN
  171. #  define PTRDIFF_MAX  _I32_MAX
  172. #endif  // _WIN64 ]

  173. #define SIG_ATOMIC_MIN  INT_MIN
  174. #define SIG_ATOMIC_MAX  INT_MAX

  175. #ifndef SIZE_MAX // [
  176. #  ifdef _WIN64 // [
  177. #     define SIZE_MAX  _UI64_MAX
  178. #  else // _WIN64 ][
  179. #     define SIZE_MAX  _UI32_MAX
  180. #  endif // _WIN64 ]
  181. #endif // SIZE_MAX ]

  182. // WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
  183. #ifndef WCHAR_MIN // [
  184. #  define WCHAR_MIN  0
  185. #endif  // WCHAR_MIN ]
  186. #ifndef WCHAR_MAX // [
  187. #  define WCHAR_MAX  _UI16_MAX
  188. #endif  // WCHAR_MAX ]

  189. #define WINT_MIN  0
  190. #define WINT_MAX  _UI16_MAX

  191. #endif // __STDC_LIMIT_MACROS ]


  192. // 7.18.4 Limits of other integer types

  193. #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260

  194. // 7.18.4.1 Macros for minimum-width integer constants

  195. #define INT8_C(val)  val##i8
  196. #define INT16_C(val) val##i16
  197. #define INT32_C(val) val##i32
  198. #define INT64_C(val) val##i64

  199. #define UINT8_C(val)  val##ui8
  200. #define UINT16_C(val) val##ui16
  201. #define UINT32_C(val) val##ui32
  202. #define UINT64_C(val) val##ui64

  203. // 7.18.4.2 Macros for greatest-width integer constants
  204. #define INTMAX_C   INT64_C
  205. #define UINTMAX_C  UINT64_C

  206. #endif // __STDC_CONSTANT_MACROS ]


  207. #endif // _MSC_STDINT_H_ ]
复制代码
以及它的更新日志:
  1. ------------------------------------------------------------------------
  2. r26 | 2009-10-02 13:36:47 +0400 | 2 lines

  3. [Issue 5] Change <stdint.h> to "stdint.h" to let compiler search for it in local directory.

  4. ------------------------------------------------------------------------
  5. r25 | 2009-09-17 23:46:49 +0400 | 2 lines

  6. [Issue 4] Fix incorrect int8_t behaviour if compiled with /J flag.

  7. ------------------------------------------------------------------------
  8. r24 | 2009-05-13 14:53:48 +0400 | 2 lines

  9. Forgot about #ifdef __cplusplus guard around 'extern "C"', so inclusion to C files has been broken.

  10. ------------------------------------------------------------------------
  11. r23 | 2009-05-12 01:27:45 +0400 | 3 lines

  12. [Issue 2] Always wrap <wchar钹?with external "C" {}.
  13. It turns out that not only Visual Studio 6 requires this, but also newer versions when compiling for ARM.

  14. ------------------------------------------------------------------------
  15. r22 | 2009-05-11 22:22:15 +0400 | 3 lines

  16. [Issue 3] Visual Studio 6 and Embedded Visual C++ 4 doesn't realize that, e.g. char has the same size as __int8 so we give up on __intX for them.
  17. his should close Issue 3 in issue tracker.

  18. ------------------------------------------------------------------------
  19. r21 | 2008-07-17 09:47:22 +0400 | 4 lines

  20. Get rid of these compiler warnings when compiling for 32-bit:
  21.   warning C4311: 'type cast' : pointer truncation from 'void *' to 'uintptr_t'
  22.   warning C4312: 'type cast' : conversion from 'uintptr_t' to 'const void *' of greater size

  23. ------------------------------------------------------------------------
  24. r20 | 2007-10-09 16:54:27 +0400 | 2 lines

  25. Better C99 conformance: macros for format specifiers should only be included in C++ implementations if __STDC_FORMAT_MACROS is defined before <inttypes.h> is included.

  26. ------------------------------------------------------------------------
  27. r19 | 2007-07-04 02:14:40 +0400 | 3 lines

  28. Explicitly cast to appropriate type INT8_MIN, INT16_MIN, INT32_MIN and INT64_MIN constants.
  29. Due to their unusual definition in Visual Studio headers (-_Ix_MAX-1) they are propagated to int and thus do not have expected type, causing VS6 strict compiler to claim about type inconsistency.

  30. ------------------------------------------------------------------------
  31. r18 | 2007-06-26 16:53:23 +0400 | 2 lines

  32. Better handling of (U)INTx_C macros - now they generate constants of exact width.

  33. ------------------------------------------------------------------------
  34. r17 | 2007-03-29 20:16:14 +0400 | 2 lines

  35. Fix typo: Miscrosoft -> Microsoft.

  36. ------------------------------------------------------------------------
  37. r16 | 2007-02-24 17:32:58 +0300 | 4 lines

  38. Remove <BaseTsd.h> include, as it is not present in Visual Studio 2005 Epxress Edition and required only for INT_PTR and UINT_PTR types.

  39. 'intptr_t' and 'uintptr_t' types now defined explicitly with #ifdef _WIN64.

  40. ------------------------------------------------------------------------
  41. r15 | 2007-02-11 20:53:05 +0300 | 2 lines

  42. More correct fix for compilation under VS6.

  43. ------------------------------------------------------------------------
  44. r14 | 2007-02-11 20:04:32 +0300 | 2 lines

  45. Bugfix: fix compiling under VS6, when stdint.h enclosed in 'extern "C" {}'.

  46. ------------------------------------------------------------------------
  47. r13 | 2006-12-13 16:53:11 +0300 | 2 lines

  48. Make _inline modifier for imaxdiv default option. Use STATIC_IMAXDIV to make it static.

  49. ------------------------------------------------------------------------
  50. r12 | 2006-12-13 16:42:24 +0300 | 2 lines

  51. Error message changed: VC6 supported from now.

  52. ------------------------------------------------------------------------
  53. r11 | 2006-12-13 16:39:33 +0300 | 2 lines

  54. All (U)INT* types changed to (unsigned) __int*. This should make stdint.h compatible with VC6.

  55. ------------------------------------------------------------------------
  56. r10 | 2006-12-13 16:20:57 +0300 | 3 lines

  57. Added INLINE_IMAXDIV define switch.
  58. If INLINE_IMAXDIV is defined imaxdiv() have static modifier. If not - it is _inline.

  59. ------------------------------------------------------------------------
  60. r9 | 2006-12-13 15:53:52 +0300 | 2 lines

  61. Error message for non-MSC compiler changed.

  62. ------------------------------------------------------------------------
  63. r8 | 2006-12-13 12:47:48 +0300 | 2 lines

  64. Added #ifndef for SIZE_MAX (it is defined in limits.h on MSVSC 8).

  65. ------------------------------------------------------------------------
  66. r7 | 2006-12-13 01:08:02 +0300 | 2 lines

  67. License chaged to BSD-derivative.

  68. ------------------------------------------------------------------------
  69. r6 | 2006-12-13 00:53:20 +0300 | 2 lines

  70. Added <wchar.h> include to avoid warnings when it is included after stdint.h.

  71. ------------------------------------------------------------------------
  72. r5 | 2006-12-12 00:58:05 +0300 | 2 lines

  73. BUGFIX: Definitions of INTPTR_MIN, INTPTR_MAX and UINTPTR_MAX for WIN32 and WIN64 was mixed up.

  74. ------------------------------------------------------------------------
  75. r4 | 2006-12-12 00:51:55 +0300 | 2 lines

  76. Rise #error if _MSC_VER is not defined. I.e. compiler other then Microsoft Visual C++ is used.

  77. ------------------------------------------------------------------------
  78. r3 | 2006-12-11 22:54:14 +0300 | 2 lines

  79. Added <limits.h> include to stdint.h.

  80. ------------------------------------------------------------------------
  81. r2 | 2006-12-11 21:39:27 +0300 | 2 lines

  82. Initial check in.

  83. ------------------------------------------------------------------------
  84. r1 | 2006-12-11 21:30:23 +0300 | 1 line

  85. Initial directory structure.
  86. ------------------------------------------------------------------------
复制代码

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2019-2-3 12:07:40 | 显示全部楼层
顶站长,小弟我记得pells C对C11标准支持的比较好,至于msvc它不管C99或者C11,我认为他自己就有一套msvc的C语言标准。
顺便提一下,补头文件对我来说是个恐怖的事情,因为大多数头文件包含别的头文件,而别的头文件又包含别的头文件,这个我经常处理不好。
回复 赞! 靠!

使用道具 举报

发表于 2019-2-9 00:53:50 | 显示全部楼层
本帖最后由 Ayala 于 2019-2-9 01:02 编辑

新版本的vs不自己包含么
stdatomic.h和atomic区别很大么
还有
cinttypes和inttypes.h
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2019-2-9 23:09:45 | 显示全部楼层
Ayala 发表于 2019-2-9 00:53
新版本的vs不自己包含么
stdatomic.h和atomic区别很大么
还有

cinttypes是C++的,inttypes.h是C的。cinttypes是C++从C那里搬运过来的。

stdatomic.h是C的,atomic是C++的,但atomic不是C++从C的stdatomic.h搬运过来的。搬运的版本是cstdatomic。
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-22 10:22 , Processed in 0.040172 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表