9

How can I test if a type is supported by a compiler? Say like uint64_t. Is there a reference somewhere I can use for learning how to test for any given types?

It is surprisingly hard to find this out via search engine. I tried "C test for data type" and many other things.

JustTired
  • 141
  • 9
  • 1
    You can just trust it to be there! If it is not, you will have *tons* of other problems as well, like 9-bit bytes, one's complement arithmetic, and non-ASCII character sets. See [Exotic architectures the standard committee cares about](http://stackoverflow.com/questions/6971886/exotic-architectures-the-standard-committee-cares-about). – Bo Persson Dec 29 '12 at 09:40
  • 2
    @Bo Persson: Some small embedded platforms (8-bit or 16-bit processors) may only support up to `uint32_t`. If you're writing e.g. a library that may run on a wide range of platforms, you might want to use `uint64_t` if it's available, or fall back to `uint32_t` only if that's all that's available. – Craig McQueen Sep 02 '13 at 23:27

2 Answers2

14

You can check that:

UINT64_MAX macro is defined after including stdint.h.

If you are not sure if c99 or higher is supported you can also enclose it in a check to __STDC_VERSION__ to be >= 199901L. Note that also that __STDC_VERSION__ macro is not present in C89/C90.

From the Standard (emphasis mine):

(C99, 7.18p4) "For each type described herein that the implementation provides,224) shall declare that typedef name and define the associated macros. Conversely, for each type described herein that the implementation does not provide, shall not declare that typedef name nor shall it define the associated macros."

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
ouah
  • 142,963
  • 15
  • 272
  • 331
  • Ah, I've been using . Not even sure now where I first found that, but it's apparently working. – JustTired Dec 29 '12 at 01:57
  • 1
    @JustTired `inttypes.h` would also be OK, as `inttypes.h` has to include `stdint.h` in C. But including `stdint.h` here would be better. – ouah Dec 29 '12 at 01:58
  • 1
    @JustTired from `(C99, 7.8p1) "The header includes the header "` – ouah Dec 29 '12 at 01:59
  • Thank you. I'm sure I can find a macro list somewhere with their respective types. – JustTired Dec 29 '12 at 02:01
  • Can you recommend a good tutorial on how to fallback to another type if it is not supported. For instance right now I have uint64_t all over my code, but if it is not supported, I don't have to rewrite the code correct? I could just typedef uint64_t to say uint32_t or what not? – JustTired Dec 29 '12 at 02:05
  • Assuming you are using c99 or higher, you can use `unsigned long long` instead of `uint64_t`. `unsigned long long` is guaranteed to be at least `64-bit` wide. `unsigned long long` may also be present on some c90 implementations as an extension. Note that on some c90 implementations `unsigned long` may also be `64-bit` wide, but you'd have to check as the `unsigned long` type is only guaranteed to be at least `32-bit` wide. – ouah Dec 29 '12 at 02:11
  • I'm not sure if sizeof(uint64_t) is any different than long long on my system, they both return 8. For that matter, so does int or long. – JustTired Dec 29 '12 at 02:13
  • To be 100% portable is very difficult. `sizeof (uint64_t)` is guaranteed to be `8` but `sizeof (unsigned long long)` can be for example `1` or `2` if the `char` implementation is respectively `64` or `32` bits. – ouah Dec 29 '12 at 02:19
  • 1
    Note that both `uint_least64_t` and `unsigned long long` are required to exist by the standard, and required to be at least 64 bits wide. – R.. GitHub STOP HELPING ICE Dec 29 '12 at 03:58
  • You probably mean `UINT64_MAX`, there is no such thing as `UINT64_MIN` in the C standard, the `_MIN` macros are only defined for the signed types. – Jens Gustedt Dec 29 '12 at 09:22
  • @R. I didn't think that was true. Do you have a reference? I thought it says something like "if there is a type capable of holding 64 bits, then `uint64_t` must be present." – Craig McQueen Oct 03 '13 at 21:25
  • 1
    @CraigMcQueen: I'm not quite sure which point you're asking about, but the reference is the C standard; in C99, 7.18 Integer types . The `[u]intNN_t` types must be exact-size (no padding) and they exist if and only if there's a matching type, and the "least" types are mandatory. There is always a type capable of holding at least 64 bits: `unsigned long long`. – R.. GitHub STOP HELPING ICE Oct 04 '13 at 03:52
  • I would recommend `uint_fast64_t` instead of `uint_least64_t`, but they're probably the same thing on most platforms anyway. – Kevin Jan 16 '15 at 17:16
  • @R.. If you're referring to C99 standard you're right to be guaranteed the existence of `uint_least64_t`.The answer includes a check for that and the question did not mention C99 - so possibly you can't rely on that being the case... – skyking Mar 30 '17 at 06:52
  • @skyking: My answer already covers how to check for C99 or later. – R.. GitHub STOP HELPING ICE Mar 30 '17 at 17:34
2

Try using it - you'll get a compiler error if it's not there. The types like uint64_t are in stdint.h.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • That's not helpful for how to handle it automatically--e.g. writing code that can use a 64-bit algorithm if `uint64_t` is available, or fall-back to a 32-bit algorithm if only `uint32_t` is present. – Craig McQueen Sep 02 '13 at 23:24
  • Why not? It's the way configure scripts detect all kinds of things. – Carl Norum Sep 02 '13 at 23:43
  • If you can detect it using just the preprocessor instead, then you don't need a configure script. That is simpler—and simpler is usually better. – Craig McQueen Sep 02 '13 at 23:55
  • @CraigMcQueen On the other side the question didn't mention the version of the C-standard. If you don't know which standard that is supported the only way seem to be to check for the availability in this straight forward way. Note that if you detect the compiler to be pre-C99 you may still have `uint64_t` available since there is nothing forbidding it in earlier standards. This is a reason why `configure` scripts does the check this way instead. In addition this kind of technique works on any type, even non-standard. – skyking Mar 30 '17 at 06:56