5

I am trying to determine at compile time that _Float16 is supported:

#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <float.h>
#ifdef FLT16_MAX
_Float16 f16;
#endif

Invocations:

# gcc trunk on linux on x86_64
$ gcc -std=c11 -pedantic -Wall -Wextra
t0.c:4:1: warning: ISO C does not support the '_Float16' type [-Wpedantic]

# clang trunk on linux on x86_64
$ clang -std=c11 -pedantic -Wall -Wextra
t0.c:4:1: error: _Float16 is not supported on this target

Here we see that both gcc and clang:

  • define FLT16_MAX
  • do not support _Float16

The main question: How to correctly determine at compile time that _Float16 is supported?

The extra question: Does the C11 (or newer) standard require to not define _MIN / _MAX macros if the corresponding floating type is not supported? For example, for integer types (<stdint.h>) it is true: "nor shall it define the associated macros" (C11, 7.20 Integer types <stdint.h>, 4). Is it the same for floating types?

UPD20211117:

  1. Invoking gcc w/o -pedantic causes the warning disappear. And _Float16 is supported. Great!
  2. Invoking clang w/o -pedantic does not cause the error disappear. Proabbly it is a bug.

Thanks to user n. 1.8e9-where's-my-share m. for the idea.

UPD20211118: gcc: with -pedantic the FLT16_MAX is defined, which is unexpected (or not?).

pmor
  • 5,392
  • 4
  • 17
  • 36
  • Because nothing barres them from defining it. It is better to have one universal header shared between implementations – 0___________ Nov 15 '21 at 16:10
  • 2
    It would improve the question to just ask #3 as the main question, and mention #2 as corollary – M.M Nov 16 '21 at 10:21
  • @M.M The question is improved. – pmor Nov 16 '21 at 16:30
  • _Float16 is not a part of the C11 standard, so you cannot invoke the standard to reason about _Float16. – n. m. could be an AI Nov 16 '21 at 16:42
  • @n.1.8e9-where's-my-sharem. `_Float16` is defined in [IEC 60559 interchange and extended types](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2601.pdf), which is Annex X. Then how to determine at compile time that Annex X is supported? For example for Annex F there is `__STDC_IEC_559__`. – pmor Nov 17 '21 at 08:43
  • This document postdates c11. It will be included in C23 I think. gcc supports it, but it warns you that this is a non-standard feature because you are using -pedantic. clang in your configuration doesn't support it, but it piggybacks on glibc which says it should be supported. It is probably a clang bug. – n. m. could be an AI Nov 17 '21 at 09:00
  • @MarkDickinson Interesting! Then who is the provider of `FLT16_MAX`? – pmor Nov 17 '21 at 12:04
  • @pmor: On further investigation, I think I don't know what I'm talking about. I'll delete my comments and let someone more knowledgeable answer. – Mark Dickinson Nov 17 '21 at 13:00
  • @n.1.8e9-where's-my-sharem. with `-pedantic` gcc warns on `_Float16` but not on `FLT16_MAX`. – pmor Nov 18 '21 at 20:26
  • @pmor Why should it? You can use any identifier at all in `#ifdef`, there is nothing non-standard in it. – n. m. could be an AI Nov 19 '21 at 04:15
  • @n.1.8e9-where's-my-sharem. Indeed. I wanted to say: with `-pedantic` the `FLT16_MAX` is defined, which is unexpected. – pmor Nov 19 '21 at 12:12
  • `-pedantic` gives you warnings about your code using non-standard language features, but `#ifdef FLT16_MAX` is not non-standard. `FLT16_MAX` normally should not be defined, `-pedantic` or not, but you asked for it by using a leading-two-underscores identifier. – n. m. could be an AI Nov 19 '21 at 12:24
  • @n.1.8e9-where's-my-sharem. Does "strict ISO C" allow "ISO C extensions"? – pmor Nov 19 '21 at 16:20

3 Answers3

1

Use clang's __is_identifier: https://clang.llvm.org/docs/LanguageExtensions.html#is-identifier

__is_identifier evaluates to 1 if the argument is just a regular identifier and not a reserved word, in the sense that it can then be used as the name of a user-defined function or variable. Otherwise it evaluates to 0.

So hopefully this code works:

#ifdef __is_identifier // Compatibility with non-clang compilers.
  #if !__is_identifier(_Float16)
    typedef _Float16 f16;
    #define FLOAT16_BUILTIN
  #endif
#endif
mostafa.elhoushi
  • 3,758
  • 1
  • 17
  • 10
0

The support of _FloatN can be determined via checking if the associated MIN / MAX (and other) macros are defined (after including float.h preceded with __STDC_WANT_IEC_60559_TYPES_EXT__).

Extra: the same principle is used to determine the support of types from stdint.h: check if the associated MIN / MAX macros are defined.

pmor
  • 5,392
  • 4
  • 17
  • 36
-3

How to correctly determine at compile time that _Float16 is supported?

Compile a program that uses _Float16. If it compiles, it means it is supported.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Consider writing a self-adaptive software. At one point you want to determine at compile time whether `_Float16` is supported. If it isn't, then you don't want "it doesn't compile". You want it to be always compiled and use `_Float16` if it is available. – pmor Jan 14 '22 at 21:47
  • 1
    So write a small program that uses `_Float16`. Compile it. If it compiles, add `HAS_FLOAT16=1` flag to your compiler. Then compile your self-adaptive software and check for `HAS_FLOAT16` flag....... ( https://cmake.org/cmake/help/latest/module/CheckTypeSize.html , https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/autoconf.html#Generic-Types ) – KamilCuk Jan 14 '22 at 23:25
  • FYI: the support of types from `stdint.h` can be determined via checking if the associated `MIN / MAX` macros are defined. Similarly the support of `_FloatN` can be determined via checking if the associated `MIN / MAX` (and other) macros are defined (after including `float.h` preceded with `__STDC_WANT_IEC_60559_TYPES_EXT__`). – pmor Jan 14 '22 at 23:49
  • @KamilCuk some prefer writing code that works with any build system out-of-the-box, without reliance on autoconf or similar. – Yakov Galka Jan 16 '23 at 23:11
  • @pmor Compiling test programs and then adjusting compiler flags for the "real" build is of course a perfectly standard technique, used extensively by autoconf and the like. – Steve Summit Jan 16 '23 at 23:11
  • @YakovGalka I like works-out-of-the-box code, too, but it's not always possible. – Steve Summit Jan 16 '23 at 23:13