SDL_begin_code.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. /* WIKI CATEGORY: BeginCode */
  19. /**
  20. * SDL_begin_code.h sets things up for C dynamic library function definitions,
  21. * static inlined functions, and structures aligned at 4-byte alignment.
  22. * If you don't like ugly C preprocessor code, don't look at this file. :)
  23. *
  24. * SDL's headers use this; applications generally should not include this
  25. * header directly.
  26. */
  27. /* This shouldn't be nested -- included it around code only. */
  28. #ifdef SDL_begin_code_h
  29. #error Nested inclusion of SDL_begin_code.h
  30. #endif
  31. #define SDL_begin_code_h
  32. #ifdef SDL_WIKI_DOCUMENTATION_SECTION
  33. /**
  34. * A macro to tag a symbol as deprecated.
  35. *
  36. * A function is marked deprecated by adding this macro to its declaration:
  37. *
  38. * ```c
  39. * extern SDL_DEPRECATED int ThisFunctionWasABadIdea(void);
  40. * ```
  41. *
  42. * Compilers with deprecation support can give a warning when a deprecated
  43. * function is used. This symbol may be used in SDL's headers, but apps are
  44. * welcome to use it for their own interfaces as well.
  45. *
  46. * SDL, on occasion, might deprecate a function for various reasons. However,
  47. * SDL never removes symbols before major versions, so deprecated interfaces
  48. * in SDL3 will remain available under SDL4, where it would be expected an
  49. * app would have to take steps to migrate anyhow.
  50. *
  51. * On compilers without a deprecation mechanism, this is defined to nothing,
  52. * and using a deprecated function will not generate a warning.
  53. *
  54. * \since This macro is available since SDL 3.1.3.
  55. */
  56. #define SDL_DEPRECATED __attribute__((deprecated))
  57. /**
  58. * A macro to tag a symbol as a public API.
  59. *
  60. * SDL uses this macro for all its public functions. On some targets, it
  61. * is used to signal to the compiler that this function needs to be exported
  62. * from a shared library, but it might have other side effects.
  63. *
  64. * This symbol is used in SDL's headers, but apps and other libraries are
  65. * welcome to use it for their own interfaces as well.
  66. *
  67. * \since This macro is available since SDL 3.1.3.
  68. */
  69. #define SDL_DECLSPEC __attribute__ ((visibility("default")))
  70. /**
  71. * A macro to set a function's calling conventions.
  72. *
  73. * SDL uses this macro for all its public functions, and any callbacks it
  74. * defines. This macro guarantees that calling conventions match between
  75. * SDL and the app, even if the two were built with different compilers
  76. * or optimization settings.
  77. *
  78. * When writing a callback function, it is very important for it to be
  79. * correctly tagged with SDLCALL, as mismatched calling conventions can
  80. * cause strange behaviors and can be difficult to diagnose. Plus, on many
  81. * platforms, SDLCALL is defined to nothing, so compilers won't be able to
  82. * warn that the tag is missing.
  83. *
  84. * This symbol is used in SDL's headers, but apps and other libraries are
  85. * welcome to use it for their own interfaces as well.
  86. *
  87. * \since This macro is available since SDL 3.1.3.
  88. */
  89. #define SDLCALL __cdecl
  90. /**
  91. * A macro to request a function be inlined.
  92. *
  93. * This is a hint to the compiler to inline a function. The compiler is free
  94. * to ignore this request. On compilers without inline support, this is
  95. * defined to nothing.
  96. *
  97. * \since This macro is available since SDL 3.1.3.
  98. */
  99. #define SDL_INLINE __inline
  100. /**
  101. * A macro to demand a function be inlined.
  102. *
  103. * This is a command to the compiler to inline a function. SDL uses this
  104. * macro in its public headers for a handful of simple functions. On compilers
  105. * without forceinline support, this is defined to `static SDL_INLINE`, which
  106. * is often good enough.
  107. *
  108. * This symbol is used in SDL's headers, but apps and other libraries are
  109. * welcome to use it for their own interfaces as well.
  110. *
  111. * \since This macro is available since SDL 3.1.3.
  112. */
  113. #define SDL_FORCE_INLINE __forceinline
  114. /**
  115. * A macro to tag a function as never-returning.
  116. *
  117. * This is a hint to the compiler that a function does not return. An example
  118. * of a function like this is the C runtime's exit() function.
  119. *
  120. * This hint can lead to code optimizations, and help analyzers understand
  121. * code flow better. On compilers without noreturn support, this is
  122. * defined to nothing.
  123. *
  124. * This symbol is used in SDL's headers, but apps and other libraries are
  125. * welcome to use it for their own interfaces as well.
  126. *
  127. * \since This macro is available since SDL 3.1.3.
  128. */
  129. #define SDL_NORETURN __attribute__((noreturn))
  130. /**
  131. * A macro to tag a function as never-returning (for analysis purposes).
  132. *
  133. * This is almost identical to SDL_NORETURN, except functions marked with this
  134. * _can_ actually return. The difference is that this isn't used for code
  135. * generation, but rather static analyzers use this information to assume
  136. * truths about program state and available code paths. Specifically, this
  137. * tag is useful for writing an assertion mechanism. Indeed, SDL_assert uses
  138. * this tag behind the scenes. Generally, apps that don't understand the
  139. * specific use-case for this tag should avoid using it directly.
  140. *
  141. * On compilers without analyzer_noreturn support, this is defined to nothing.
  142. *
  143. * This symbol is used in SDL's headers, but apps and other libraries are
  144. * welcome to use it for their own interfaces as well.
  145. *
  146. * \since This macro is available since SDL 3.1.3.
  147. */
  148. #define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
  149. /**
  150. * A macro to signal that a case statement without a `break` is intentional.
  151. *
  152. * C compilers have gotten more aggressive about warning when a switch's
  153. * `case` block does not end with a `break` or other flow control statement,
  154. * flowing into the next case's code, as this is a common accident that leads
  155. * to strange bugs. But sometimes falling through to the next case is the
  156. * correct and desired behavior. This symbol lets an app communicate this
  157. * intention to the compiler, so it doesn't generate a warning.
  158. *
  159. * It is used like this:
  160. *
  161. * ```c
  162. * switch (x) {
  163. * case 1:
  164. * DoSomethingOnlyForOne();
  165. * SDL_FALLTHROUGH; // tell the compiler this was intentional.
  166. * case 2:
  167. * DoSomethingForOneAndTwo();
  168. * break;
  169. * }
  170. * ```
  171. *
  172. * \since This macro is available since SDL 3.1.3.
  173. */
  174. #define SDL_FALLTHROUGH [[fallthrough]]
  175. /**
  176. * A macro to tag a function's return value as critical.
  177. *
  178. * This is a hint to the compiler that a function's return value should not
  179. * be ignored.
  180. *
  181. * If an NODISCARD function's return value is thrown away (the function is
  182. * called as if it returns `void`), the compiler will issue a warning.
  183. *
  184. * While it's generally good practice to check return values for errors,
  185. * often times legitimate programs do not for good reasons. Be careful
  186. * about what functions are tagged as NODISCARD. It operates best when
  187. * used on a function that's failure is surprising and catastrophic; a good
  188. * example would be a program that checks the return values of all its
  189. * file write function calls but not the call to close the file, which it
  190. * assumes incorrectly never fails.
  191. *
  192. * Function callers that want to throw away a NODISCARD return value can
  193. * call the function with a `(void)` cast, which informs the compiler the
  194. * act is intentional.
  195. *
  196. * On compilers without nodiscard support, this is defined to nothing.
  197. *
  198. * \since This macro is available since SDL 3.1.3.
  199. */
  200. #define SDL_NODISCARD [[nodiscard]]
  201. /**
  202. * A macro to tag a function as an allocator.
  203. *
  204. * This is a hint to the compiler that a function is an allocator, like
  205. * malloc(), with certain rules. A description of how GCC treats this
  206. * hint is here:
  207. *
  208. * https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
  209. *
  210. * On compilers without allocator tag support, this is defined to nothing.
  211. *
  212. * Most apps don't need to, and should not, use this directly.
  213. *
  214. * \since This macro is available since SDL 3.1.3.
  215. */
  216. #define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
  217. /**
  218. * A macro to tag a function as returning a certain allocation.
  219. *
  220. * This is a hint to the compiler that a function allocates and returns a
  221. * specific amount of memory based on one of its arguments.
  222. * For example, the C runtime's malloc() function could use this macro
  223. * with an argument of 1 (first argument to malloc is the size of the
  224. * allocation).
  225. *
  226. * On compilers without alloc_size support, this is defined to nothing.
  227. *
  228. * Most apps don't need to, and should not, use this directly.
  229. *
  230. * \since This macro is available since SDL 3.1.3.
  231. */
  232. #define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
  233. /**
  234. * A macro to tag a pointer variable, to help with pointer aliasing.
  235. *
  236. * A good explanation of the restrict keyword is here:
  237. *
  238. * https://en.wikipedia.org/wiki/Restrict
  239. *
  240. * On compilers without restrict support, this is defined to nothing.
  241. *
  242. * \since This macro is available since SDL 3.1.3.
  243. */
  244. #define SDL_RESTRICT __restrict__
  245. /* end of wiki documentation section. */
  246. #endif
  247. #ifndef SDL_DEPRECATED
  248. # if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
  249. # define SDL_DEPRECATED __attribute__((deprecated))
  250. # elif defined(_MSC_VER)
  251. # define SDL_DEPRECATED __declspec(deprecated)
  252. # else
  253. # define SDL_DEPRECATED
  254. # endif
  255. #endif
  256. #ifndef SDL_UNUSED
  257. # ifdef __GNUC__
  258. # define SDL_UNUSED __attribute__((unused))
  259. # else
  260. # define SDL_UNUSED
  261. # endif
  262. #endif
  263. /* Some compilers use a special export keyword */
  264. #ifndef SDL_DECLSPEC
  265. # if defined(SDL_PLATFORM_WINDOWS)
  266. # ifdef DLL_EXPORT
  267. # define SDL_DECLSPEC __declspec(dllexport)
  268. # else
  269. # define SDL_DECLSPEC
  270. # endif
  271. # else
  272. # if defined(__GNUC__) && __GNUC__ >= 4
  273. # define SDL_DECLSPEC __attribute__ ((visibility("default")))
  274. # else
  275. # define SDL_DECLSPEC
  276. # endif
  277. # endif
  278. #endif
  279. /* By default SDL uses the C calling convention */
  280. #ifndef SDLCALL
  281. #if defined(SDL_PLATFORM_WINDOWS) && !defined(__GNUC__)
  282. #define SDLCALL __cdecl
  283. #else
  284. #define SDLCALL
  285. #endif
  286. #endif /* SDLCALL */
  287. /* Force structure packing at 4 byte alignment.
  288. This is necessary if the header is included in code which has structure
  289. packing set to an alternate value, say for loading structures from disk.
  290. The packing is reset to the previous value in SDL_close_code.h
  291. */
  292. #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
  293. #ifdef _MSC_VER
  294. #pragma warning(disable: 4103)
  295. #endif
  296. #ifdef __clang__
  297. #pragma clang diagnostic ignored "-Wpragma-pack"
  298. #endif
  299. #ifdef __BORLANDC__
  300. #pragma nopackwarning
  301. #endif
  302. #ifdef _WIN64
  303. /* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
  304. #pragma pack(push,8)
  305. #else
  306. #pragma pack(push,4)
  307. #endif
  308. #endif /* Compiler needs structure packing set */
  309. #ifndef SDL_INLINE
  310. #ifdef __GNUC__
  311. #define SDL_INLINE __inline__
  312. #elif defined(_MSC_VER) || defined(__BORLANDC__) || \
  313. defined(__DMC__) || defined(__SC__) || \
  314. defined(__WATCOMC__) || defined(__LCC__) || \
  315. defined(__DECC) || defined(__CC_ARM)
  316. #define SDL_INLINE __inline
  317. #ifndef __inline__
  318. #define __inline__ __inline
  319. #endif
  320. #else
  321. #define SDL_INLINE inline
  322. #ifndef __inline__
  323. #define __inline__ inline
  324. #endif
  325. #endif
  326. #endif /* SDL_INLINE not defined */
  327. #ifndef SDL_FORCE_INLINE
  328. #ifdef _MSC_VER
  329. #define SDL_FORCE_INLINE __forceinline
  330. #elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
  331. #define SDL_FORCE_INLINE __attribute__((always_inline)) static __inline__
  332. #else
  333. #define SDL_FORCE_INLINE static SDL_INLINE
  334. #endif
  335. #endif /* SDL_FORCE_INLINE not defined */
  336. #ifndef SDL_NORETURN
  337. #ifdef __GNUC__
  338. #define SDL_NORETURN __attribute__((noreturn))
  339. #elif defined(_MSC_VER)
  340. #define SDL_NORETURN __declspec(noreturn)
  341. #else
  342. #define SDL_NORETURN
  343. #endif
  344. #endif /* SDL_NORETURN not defined */
  345. #ifdef __clang__
  346. #if __has_feature(attribute_analyzer_noreturn)
  347. #define SDL_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
  348. #endif
  349. #endif
  350. #ifndef SDL_ANALYZER_NORETURN
  351. #define SDL_ANALYZER_NORETURN
  352. #endif
  353. /* Apparently this is needed by several Windows compilers */
  354. #ifndef __MACH__
  355. #ifndef NULL
  356. #ifdef __cplusplus
  357. #define NULL 0
  358. #else
  359. #define NULL ((void *)0)
  360. #endif
  361. #endif /* NULL */
  362. #endif /* ! macOS - breaks precompiled headers */
  363. #ifndef SDL_FALLTHROUGH
  364. #if (defined(__cplusplus) && __cplusplus >= 201703L) || \
  365. (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
  366. #define SDL_FALLTHROUGH [[fallthrough]]
  367. #else
  368. #if defined(__has_attribute) && !defined(__SUNPRO_C) && !defined(__SUNPRO_CC)
  369. #define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__)
  370. #else
  371. #define SDL_HAS_FALLTHROUGH 0
  372. #endif /* __has_attribute */
  373. #if SDL_HAS_FALLTHROUGH && \
  374. ((defined(__GNUC__) && __GNUC__ >= 7) || \
  375. (defined(__clang_major__) && __clang_major__ >= 10))
  376. #define SDL_FALLTHROUGH __attribute__((__fallthrough__))
  377. #else
  378. #define SDL_FALLTHROUGH do {} while (0) /* fallthrough */
  379. #endif /* SDL_HAS_FALLTHROUGH */
  380. #undef SDL_HAS_FALLTHROUGH
  381. #endif /* C++17 or C2x */
  382. #endif /* SDL_FALLTHROUGH not defined */
  383. #ifndef SDL_NODISCARD
  384. #if (defined(__cplusplus) && __cplusplus >= 201703L) || \
  385. (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L)
  386. #define SDL_NODISCARD [[nodiscard]]
  387. #elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
  388. #define SDL_NODISCARD __attribute__((warn_unused_result))
  389. #elif defined(_MSC_VER) && (_MSC_VER >= 1700)
  390. #define SDL_NODISCARD _Check_return_
  391. #else
  392. #define SDL_NODISCARD
  393. #endif /* C++17 or C23 */
  394. #endif /* SDL_NODISCARD not defined */
  395. #ifndef SDL_MALLOC
  396. #if defined(__GNUC__) && (__GNUC__ >= 3)
  397. #define SDL_MALLOC __attribute__((malloc))
  398. /** FIXME
  399. #elif defined(_MSC_VER)
  400. #define SDL_MALLOC __declspec(allocator) __desclspec(restrict)
  401. **/
  402. #else
  403. #define SDL_MALLOC
  404. #endif
  405. #endif /* SDL_MALLOC not defined */
  406. #ifndef SDL_ALLOC_SIZE
  407. #if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
  408. #define SDL_ALLOC_SIZE(p) __attribute__((alloc_size(p)))
  409. #elif defined(_MSC_VER)
  410. #define SDL_ALLOC_SIZE(p)
  411. #else
  412. #define SDL_ALLOC_SIZE(p)
  413. #endif
  414. #endif /* SDL_ALLOC_SIZE not defined */
  415. #ifndef SDL_ALLOC_SIZE2
  416. #if (defined(__clang__) && __clang_major__ >= 4) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
  417. #define SDL_ALLOC_SIZE2(p1, p2) __attribute__((alloc_size(p1, p2)))
  418. #elif defined(_MSC_VER)
  419. #define SDL_ALLOC_SIZE2(p1, p2)
  420. #else
  421. #define SDL_ALLOC_SIZE2(p1, p2)
  422. #endif
  423. #endif /* SDL_ALLOC_SIZE2 not defined */