可靠检测C编译器是否对所有enum枚举使用int类型 解决Fortran-C互操作警告
检测C枚举类型大小消除gfortran编译警告
为实现跨语言互操作,需要在编译配置阶段检测C编译器为枚举(enum)类型选用的整数类型大小。已查阅的相关问题结论如下:
- 《What is the size of an enum in C?》:枚举大小由编译器和系统配置共同决定。
- 《Specifying size of enum type in C》:给出了突破标准C常规约定的编译器相关实现方案,本次不需要修改枚举的底层类型,仅需要获知当前平台的实际情况。
- 《Is the sizeof(enum) == sizeof(int), always?》:不能盲目假设枚举大小等于int大小,仅需要检测当前平台是否符合该条件,再基于该结论做适配。
当前具体需求是消除gfortran编译如下代码时抛出的警告:
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
使用的编译指令(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
如果可以确认当前平台上所有枚举都以C int类型传递,就可以直接将代码中的enu_type_kind替换为c_int(该修改不会触发警告)。本次不需要处理使用__attribute__((packed))的特殊C代码,目标是实现代码可移植的同时尽可能减少编译警告。
内容的提问来源于stack exchange,提问作者TJahns
相关产品推荐
相关产品推荐

