For language interoperability, I want to detect the size of integral type used for enums by the C compiler at configure time. I've already had a look at the following questions:
- What is the size of an enum in C? which tells me that it depends on the compiler and system configuration.
- Specifying size of enum type in C which mostly gives compiler-dependent context about breaking out of the usual conventions of standard C, but I don't want to steer, only to know.
- Is the sizeof(enum) == sizeof(int), always? Tells me I can't blindly assume the above, but I just want to detect if I'm on a platform where it's true and only then use that knowledge.
Specifically, I wish to get rid of the compiler warning by gfortran for source like the following:
SUBROUTINE fwrap(another_int)
IMPLICIT NONE
INTEGER, INTENT(in) :: another_int
ENUM, BIND(c)
ENUMERATOR :: enu_a, enu_b
END ENUM
INTEGER, PARAMETER :: enu_type_kind = KIND(enu_a)
INTERFACE
SUBROUTINE wrapped_c(enu) BIND(C, name='wrapped_c')
IMPORT:: enu_type_kind
INTEGER(enu_type_kind), VALUE :: enu
END SUBROUTINE wrapped_c
END INTERFACE
IF (another_int < 0_enu_type_kind .OR. &
another_int > enu_b) &
CALL abort()
CALL wrapped_c(INT(another_int, enu_type_kind))
END SUBROUTINE fwrap
Compiler invocation (gfortran 11.1):
$ gfortran -c -o enum-warn.o -Wall -Wextra -Wconversion -Wstrict-overflow enum-warn.f90
enum-warn.f90:9:28:
9 | SUBROUTINE wrapped_c(enu) BIND(C, name='wrapped_c')
| 1
Warning: Variable 'enu' at (1) is a dummy argument of the BIND(C) procedure 'wrapped_c' but may not be C interoperable [https://gcc.gnu.org/onlinedocs/gfortran/Error-and-Warning-Options.html#index-Wc-binding-type-Wc-binding-type]
And if I knew that all enums are passed as C int on a platform, I could just substitute c_int for enu_type_kind in the above (which does not raise the warning). I'm not particularly interested in C code that uses __attribute__((packed))
because I'm aiming for portable code, while still getting as few warnings as possible.