2015-09-10 1 views
0

La valeur de selected_int_kind(int16) apparaît à 1 au lieu de 2. Est-ce un bogue de compilateur?Précision entière dans le Fortran moderne

Dans la sortie suivante, veuillez noter l'écart pour bint qui est censé être 2 octets, INT16. (Les annotations < === ont été ajoutées pour plus de clarté.)

compiler version = GCC version 5.1.0 
compiler options = -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -Og -Wall -Wextra -Wconversion -Wpedantic -fcheck=bounds -fmax-errors=5 
execution command = ./a.out 

Number of bytes in type default = 4 
Number of bytes in type int_8 = 1 
Number of bytes in type int_16 = 2   <=== 
Number of bytes in type int_32 = 4 
Number of bytes in type int_64 = 8 
Number of bytes in type int_a = 1 
Number of bytes in type int_b = 1   <=== 
Number of bytes in type int_c = 2 
Number of bytes in type int_d = 4 
Value of aint = 1 
Value of bint = 1       <=== 
Value of cint = 2 
Value of dint = 4 
Value of selected_int_kind (INT16) = 1 <=== 

Le code suivant est fourni pour permettre aux lecteurs d'enquêter sur ce problème. L'affectation en question est à la ligne 13.

program bytes 
    use iso_fortran_env 
    implicit NONE 

    integer   :: default 

    integer (int8 ) :: int_8 
    integer (int16) :: int_16 
    integer (int32) :: int_32 
    integer (int64) :: int_64 

    integer, parameter :: aint = selected_int_kind (INT8) 
    integer, parameter :: bint = selected_int_kind (INT16) 
    integer, parameter :: cint = selected_int_kind (INT32) 
    integer, parameter :: dint = selected_int_kind (INT64) 

    integer (aint) :: int_a 
    integer (bint) :: int_b 
    integer (cint) :: int_c 
    integer (dint) :: int_d 

    character (len = *), parameter :: c_options = compiler_options() 
    character (len = *), parameter :: c_version = compiler_version() 
    character (len = 255)   :: cmd = " " 

     call get_command (cmd) 

     write (*, '( "compiler version = ", g0 )') c_version 
     write (*, '( "compiler options = ", g0 )') trim (c_options) 
     write (*, '( "execution command = ", g0, /)') trim (cmd) 

     write (* , 100) 'default', sizeof (default) 

     write (* , 100) 'int_8', sizeof (int_8) 
     write (* , 100) 'int_16', sizeof (int_16) 
     write (* , 100) 'int_32', sizeof (int_32) 
     write (* , 100) 'int_64', sizeof (int_64) 

     write (* , 100) 'int_a', sizeof (int_a) 
     write (* , 100) 'int_b', sizeof (int_b) 
     write (* , 100) 'int_c', sizeof (int_c) 
     write (* , 100) 'int_d', sizeof (int_d) 

     write (* , 110) 'aint', aint 
     write (* , 110) 'bint', bint 
     write (* , 110) 'cint', cint 
     write (* , 110) 'dint', dint 

     write (* , 110) 'selected_int_kind (INT16)', selected_int_kind (INT16) 

    100 format ("Number of bytes in type ", g0, " = ", g0) 
    110 format ("Value of ", g0, " = ", g0) 

end program bytes 

Répondre

5

Ce n'est pas un bogue. Les normes (Fortran 95 13.14.94, Fortran 2003 13.7.105 et Fortran 2008 13.7.146) ont à dire au sujet selected_int_kind(R):

Argument. R doit être un scalaire entier.

Valeur de résultat. Le résultat a une valeur égale à la valeur du paramètre de type kind d'un type entier qui représente toutes les valeurs n dans la plage -10 R < n R, ou si aucun paramètre de type de ce type n'est disponible sur le processeur, le résultat est -1. Si plus d'un paramètre de type kind répond au critère, la valeur renvoyée est celle qui a la plus petite plage d'exposant décimal, à moins qu'il y en ait plusieurs, auquel cas la plus petite de ces valeurs est retournée.

Cela signifie, si int16 se trouve être 2 sur votre plate-forme, selected_int_kind(2) retournera le genre de type le plus petit entier capable de représenter la plage -100 à +100, qui est un seul octet avec une taille de stockage 1, la valeur int8 est renvoyée.

La sortie d'un simple programme ci-dessous devrait montrer comment cela fonctionne:

Value of int8   1 
Value of int16   2 
Value of int32   4 
Value of int64   8 
Value of selected_int_kind(1)   1 
Value of selected_int_kind(2)   1 
Value of selected_int_kind(3)   2 
Value of selected_int_kind(4)   2 
Value of selected_int_kind(5)   4 
Value of selected_int_kind(6)   4 
Value of selected_int_kind(7)   4 
Value of selected_int_kind(8)   4 
Value of selected_int_kind(9)   4 
Value of selected_int_kind(10)   8 
Value of selected_int_kind(11)   8 
Value of selected_int_kind(12)   8 
Value of selected_int_kind(13)   8 
Value of selected_int_kind(14)   8 
Value of selected_int_kind(15)   8 
Value of selected_int_kind(16)   8 
Value of selected_int_kind(17)   8 
Value of selected_int_kind(18)   8 
Value of selected_int_kind(19)   16 
Value of selected_int_kind(20)   16 
Value of selected_int_kind(21)   16 
Value of selected_int_kind(22)   16 

This file was compiled by GCC version 5.2.0 using the options -mtune=generic -march=x86-64 -std=f2008 
+1

Grande réponse et belle démonstration. – dantopa