You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无gfortran警告的情况下用255等数值初始化Fortran字符数组

问题背景

我有一段用于处理气象格式GRIB2字节打包的Fortran代码,编写测试代码时需要初始化一个字符数组,代码如下:

! Storage for the grib2 message we are constructing.
integer, parameter :: lcgrib = 191
character, dimension(lcgrib) :: cgrib
! This is the GRIB2 message we expect to get.
character(kind = int8) :: expected_cgrib(lcgrib) = (/  achar( 71), achar( 82),&
     & achar( 73), achar( 66), achar(  0), achar(  0), achar(  0),&
     & achar(  2), achar(  0), achar(  0), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar(191), achar(  0),&
     & achar(  0), achar(  0), achar( 21), achar(  1), achar(  0),&
     & achar(  7), achar(  0), achar(  4), achar(  2), achar( 24),&
     & achar(  0), achar(  7), achar(229), achar( 11), achar( 13),&
     & achar( 15), achar( 59), achar( 59), achar(  1), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar(  8), achar(  2),&
     & achar(  1), achar(  2), achar(  3), achar(  0), achar(  0),&
     & achar(  0), achar( 72), achar(  3), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar(  4), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar(  1), achar(  0),&
     & achar(  0), achar(  0), achar(  1), achar(  1), achar(  0),&
     & achar(  0), achar(  0), achar(  1), achar(  1), achar(  0),&
     & achar(  0), achar(  0), achar(  1), achar(  0), achar(  0),&
     & achar(  0), achar(  2), achar(  0), achar(  0), achar(  0),&
     & achar(  2), achar(  0), achar(  0), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar( 45), achar(  0), achar(  0),&
     & achar(  0), achar( 91), achar(  0), achar(  0), achar(  0),&
     & achar(  0), achar( 55), achar(  0), achar(  0), achar(  0),&
     & achar(101), achar(  0), achar(  0), achar(  0), achar(  5),&
     & achar(  0), achar(  0), achar(  0), achar(  5), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar( 34), achar(  4),&
     & achar(  0), achar(  0), achar(  0), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar(  0), achar(  0),&
     & achar( 12), achar( 59), achar(  0), achar(  0), achar(  0),&
     & achar(  0), achar(  0), achar(  1), achar(  1), achar(  0),&
     & achar(  0), achar(  0), achar(  1), achar(  2), achar(  1),&
     & achar(  0), achar(  0), achar(  0), achar(  1), achar(  0),&
     & achar(  0), achar(  0), achar( 21), achar(  5), achar(  0),&
     & achar(  0), achar(  0), achar(  4), achar(  0), achar(  0),&
     & achar( 65), achar( 48), achar(  0), achar(  0), achar(  0),&
     & achar(  1), achar(  0), achar(  1), achar(  8), achar(  0),&
     & achar(  0), achar(  0), achar(  0), achar(  6), achar(  6),&
     & achar(255), achar(  0), achar(  0), achar(  0), achar(  9),&
     & achar(  7), achar(  0), achar(  1), achar(  1), achar(  2),&
     & achar( 55), achar( 55), achar( 55), achar( 55) /)
报错信息

使用GNU gfortran编译时抛出如下错误:

84 |        & achar(255), achar(  0), achar(  0), achar(  0), achar(  9),&
      |               1
Error: Argument of ACHAR function at (1) outside of range [0,127] [-Werror=surprising]
问题描述

报错原因是初始化字符数组的部分整型值超过127,不属于ASCII定义范围。有没有不需要显式关闭告警就能避免该问题的方法?Fortran中是否支持用单字节无符号整数值序列初始化字符数组?


解决方法

achar()默认对应ASCII字符集,参数合法范围就是0-127,超出范围触发告警属于正常的静态检查逻辑。可以用以下两种标准Fortran语法解决,不需要关闭任何编译告警:

  • 方法一:使用transfer()函数直接做类型转换
    transfer()是Fortran标准内置的内存拷贝转换函数,不会做字符集范围校验,直接把二进制内容按目标类型解析,完全适配0-255的单字节取值场景。
    首先在代码开头引入标准内置模块获取int8类型定义:
use, intrinsic :: iso_fortran_env, only: int8

然后把原来的初始化逻辑替换为:

character(kind=int8) :: expected_cgrib(lcgrib) = transfer([ &
    71_int8, 82_int8, 73_int8, 66_int8, 0_int8, 0_int8, 0_int8, &
    2_int8, 0_int8, 0_int8, 0_int8, 0_int8, 0_int8, 0_int8, 0_int8, &
    191_int8, 0_int8, 0_int8, 0_int8, 21_int8, 1_int8, 0_int8, &
    ! 剩余数值按原顺序补充,所有数值都加_int8后缀指定为单字节整数 &
    55_int8, 55_int8, 55_int8, 55_int8], expected_cgrib)

这种方法是跨编译器兼容的标准写法,不会产生任何告警,也不会出现字节序问题,非常适合二进制格式的初始化场景。

  • 方法二:给achar()指定kind参数
    如果不想修改大量初始化代码,可以直接给achar()增加kind入参,明确指定生成单字节字符,gfortran就不会再做ASCII范围校验:
    把原来的achar(255)修改为achar(255, kind=int8)即可,所有超出127的数值都按此规则修改。

内容的提问来源于stack exchange,提问作者Edward Hartnett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:54:07