Silverfrost Forums

Welcome to our forums

An unexpected single step exception has occurred

13 Jun 2011 10:34 #8397

Like this sparge. 😄

The syntax for defining a variable and the return type of a function is the same (in Fortran 77, and therefore in Fortran 9x too). You think you are declaring a variable as character3 but you could equally be declariing a function of character3.

Have a look at the code below.

I moved your module to the head of the file (just so I could put it all in one file), but I have not changed anything in it. These three routines are valid Fortran code (if they are very ugly and contrived).

So, if the module is valid here, it must be valid in your example too. This must be the case since we require that the module should be capable of being compiled separately, without any knowledge as to how it is to be used, provided the interface is followed.

! Nothing has changed in this module
module knots
integer, parameter :: nb = 3
contains
character (len = nb) function chaout (chainp)
character (len = nb) chainp
integer b, inp (nb)
do b = 1, nb
inp (b) = ichar (chainp (b)) ! the error is here
end do
chaout = char (inp (2)) // char (inp (3)) // char (inp (1))
end function chaout
end module knots


program strung_out
use knots
EXTERNAL chainp  ! << ADDED. Note it only goes in here. Not in the function chaout
character (len = nb) chainp, chance  ! << Changed to declare type of function chainp
chance = chaout (chainp) ! Pass the external function
print *, chance ! prints yzx
stop
end program strung_out


! EXTERNAL FUNCTION
character(len=3) function chainp(p)
integer p
character(len=3) :: chintz
chintz = 'xyz'
chainp = chintz(p:p)
end function chainp
13 Jun 2011 11:48 #8402

Quoted from davidb You think you are declaring a variable as character3 but you could equally be declariing a function of character3 ... So, if the module is valid here, it must be valid in your example too.

Variable character3 or function character3, neither is a legitimate argument to pass to ICHAR, as I understand it (and as the FTN95 manual documents it). From the FTN95 help file for ICHAR:

Syntax INTEGER FUNCTION ICHAR(C) CHARACTER C

Description C is a character of length one.

Yes, the routines are ugly and contrived. They are contrived to make a point. I do get the (different) point that the module must be able to be compiled separately! Forget the code order thing, it is a red herring - I *do *compile the module separately.

You appear to be saying that the module compiles and therefore it is valid? So by definition it is impossible to demonstrate any compiler bug if that bug consists of compiling something that ought not to compile?!

I just tried to compile this code fragment, fully expecting FTN95 to object. Much to my surprise, it did not. The code compiles and runs. That does not make it valid code!

        program eyechar
        character (len = 3) c
        integer i
        c = 'abc'
        i = ichar (c)
        stop
        end

I found a Microsoft FORTRAN support page that says ICHAR will discard all but the first character if it is passed a character variable of length greater than 1. That is what is happening here. Whether it is what *should *happen, I don't know. ICHAR is a standard intrinsic function, and therefore its behaviour should be fully documented by the standard, and that behaviour and documentation should be the same for all compilers. What ICHAR should do if passed a character variable of length greater than 1 is, I guess, a question that can only be answered by the standard, and I don't have a copy ...

13 Jun 2011 12:13 #8403

I wasn't suggesting that because it compiles its correct code, rather it looks correct code so it should not give an error on compilation.

Anyway, you might be right. I don't have the Standard here either.

For what its worth the documentation for Gfortran says this (the bold emphasis is mine):

Description: ICHAR(C) returns the code for the character in the first character position of C in the system's native character set. The correspondence between characters and their codes is not necessarily the same across different GNU Fortran implementations.

Standard: Fortran 95 and later, with KIND argument Fortran 2003 and later

Class: Elemental function

Syntax: RESULT = ICHAR(C [, KIND])

Arguments:

C 	**Shall be a scalar CHARACTER**, with INTENT(IN)
KIND 	(Optional) An INTEGER initialization expression indicating the kind parameter of the result.

And microsoft says this:

'The character string in each case must be a single character CHARACTER*1. If the character string is longer than one, the ICHAR function converts only the first character of the value. '

13 Jun 2011 12:52 (Edited: 13 Jun 2011 11:37) #8404

In ICHAR(C), C can be a character1 variable or a character1 array. Where C is character*n, is not covered by the standard, but FTN95 only considers the first character.

I'm with Andy here, there should have been some warning, as a dummy function should not have been assumed. If you create an .xrf report, CHAINP is FUNCTION, ARGUMENT :: CHAINP, no mention of CHARACTER(3) ??

Have a look at the error in the following example. On checking argument consistency, ZZ is identified as wrong but not CHIMP(edit: should be CHAINP).

John

        module knots 
        integer, parameter :: nb = 3 
        contains 
        subroutine charcoal (champ, chimp, zz) 
        character (len = nb) champ, chimp 
        champ = chaout (chimp, zz) 
        end subroutine charcoal 
        character (len = nb) function chaout (chainp, zz) 
        character (len = nb) chainp 
        integer b, inp (nb) 
        do b = 1, nb 
          inp (b) = ichar (chainp (b)) + zz(b) ! the error is here 
        end do 
        chaout = char (inp (2)) // char (inp (3)) // char (inp (1)) 
        end function chaout 
        end module knots 

        program strung_out 
        use knots 
        character (len = nb) chintz, chance 
        external zz
        chintz = 'xyz' 
        call charcoal (chance, chintz, zz) 
        stop 
        end program strung_out 

        function zz(i)
        zz = i
        end function zz
13 Jun 2011 3:50 #8406

Quoted from JohnCampbell Where C is character*n, is not covered by the standard, but FTN95 only considers the first character.

John/David,

I looked a bit harder - I had forgotten that http://www.fortran.com/ provides a pretty exhaustive stock of FORTRAN standard documents. And the final draft FORTRAN 95 standard, which seems to be as close as we ever got to a FORTRAN 95 standard (it is supplemented by 6 other documents), has the following to say on the subject of ICHAR:

*13.14.45 ICHAR (C) Description. Returns the position of a character in the processor collating sequence associated with the kind type parameter of the character.

Class. Elemental function.

Argument. C shall be of type character and of length one. Its value shall be that of a character capable of representation in the processor.

Result Characteristics. Default integer.

Result Value. The result is the position of C in the processor collating sequence associated with the kind type parameter of C and is in the range , where is the number of characters in the collating sequence. For any characters C and D capable of representation in the processor, C .LE. D is true if and only if ICHAR (C) .LE. ICHAR (D) is true and C .EQ. D is true if and only if ICHAR (C) .EQ. ICHAR (D) is true.

Example. ICHAR ('X') has the value 88 on a processor using the ASCII collating sequence for the default character type.*

It seems completely unambiguous to me. 'Argument ... shall be of type character and of length one'. So lengths greater than one are not allowed; and a compiler that adopts a 'pragmatic' implementation of ICHAR, that works with the first character of an argument of length greater than one instead of diagnosing an error, is not adhering to the standard.

Incidentally, the FORTRAN 90 standard is even more unequivocal: it says 'C *must *be of type character and of length one' (italic mine).

The final draft FORTRAN 2003 standard, and the FORTRAN 2008 standard, revert to the use of 'shall' rather than must.

What is the point of a standards document if something as unambiguous as this can be interpreted so pragmatically? By this criterion, it would be scarcely more outrageous if a compiler interpreted the result of ICHAR, when passed any old data type at all, to be the result of passing it just the first byte. (FTN95 is not *this *pragmatic, by the way; I checked 😃 )

The Microsoft documentation is pretty funny. Unlike the GFORTRAN documentation (which says only how their version of the function actually behaves), the Microsoft documentation does at least acknowledge how the function is supposed to behave, before going on to ride semi-roughshod all over it. It reminds me of Groucho Marx's line 'Those are my principles, and if you don't like them ... well, I have others'.

Andy

13 Jun 2011 4:17 #8408

Hmmm ok I agree. Just have to wait and see what support thinks about it and whether a fix can be scheduled for the next release. It shouldn't be too difficult to fix.

13 Jun 2011 11:41 #8409

Andy,

It is interesting that the definition you quoted does not refer specifically to support of array syntax, which is supported by Lahey, Ftn95, Intel and a number of books.

My copy of the 'Standard' is J3/97-007R2. I wonder when the final version was published and by whom.

John

14 Jun 2011 9:30 #8411

Hi John,

That's the version I was looking at too. I started to put those numbers in my post then I took them out again when I realised I couln't make head or tail of the 'genealogy'. That one for example ... if you look at the various versions of it on the Information page here:

http://www.fortran.com/

The document itself refers to itself on the front page as J3/97-007R2, but the main link to it (which of course only lets you buy it, not actually see it) talks about ISO/IEC 1539-1:1997, and if you follow that link it resolves to a page that talks about a document called ISO/IEC 1539-1:2004, which revises ISO/IEC 1539-1:1997 and two other corrigenda documents (all of which are now woithdrawn), and is in turn revised by ISO/IEC 1539-1:2010 :roll: and the 2004 and 2010 versions are apparently the FORTRAN 2003 and FORTRAN 2008 standards :roll: :roll: :roll:

So as far as I can see, the FORTRAN95 standard never actually did get finalized. It just got rolled up into the 2003 version (which also stayed as a final draft) and that in turn got rolled up into the FORTRAN 2008 version (which I note is finally a standard again).

By 'support of array syntax' I presume you mean the ability to pass an array of CHARACTER*1 (as you pointed out yesterday) and get back an array of INTEGER? I presume this is not mentioned specifically because it is covered generically by virtue of ICHAR (along with a load of other intrinsics) being elemental. This prompted me to check that FTN95's ICHAR does behave elementally, and it does. This works as it should:

        program eyechar
        character c (26)
        integer j, i (26)
        do j = 1, 26
          c (j) = char (j + 64)
        end do
        i = ichar (c)
        stop
        end

If c is defined to be of length greater than 1, ICHAR (mis)behaves elementally the same way as it does with a scalar argument i.e. it works with only the first character of each element.

Andy

15 Jun 2011 12:13 #8418

I got my copy of the fortran 95 document some time ago. The latest info on the different versions (95, 03 and 08) can be found at http://j3-fortran.org/. It appears that the 95 .pdf is no longer available.

To repeat my previous comment, everyone should have a look at the 08 draft. I am quite concerned about where the J3 committe is taking the Fortran language. It is a massive change from what Fortran 95 is. It looks like a language rewrite to allow C programmers to use Fortran. I think the number of programmers that would use the features required in the 08 standard would not justify the expense of developing the compiler. We've seen what the .net development had on the viability of Salford and Lahey. I'd like to know how many users there are expected for the 08 features in the fortran standard.

John

15 Jun 2011 7:37 #8419

To play devil's advocate, then ... if it is going to be too expensive for anyone to develop a FORTRAN 2008 compiler, and not many people would want to use it anyway, we can all keep using battle-tested FORTRAN 95 compilers and everyone is happy. No?

15 Jun 2011 11:57 #8422

In one of my Fortran books it says that when a CHARACTER dummy argument is declared to have a specific length, the actual argument must be the same length or longer. If it is longer, the leading characters are passed up to the specified length.

See the code below (which compiles and runs OK).

If this is the correct behaviour, then it possibly provides a 'consistency' argument for the behaviour seen with ICHAR (though ICHAR is an intrinsic and different rules might apply). But I don't know if there's a general rule about this in the standard for Fortran 95, or if its just a F2003 extension that is supported -- if there is ICHAR could be off the hook. :?:

This is in the Fortran 2003 standard:

'*Fortran 2003, 12.4.1.2 Actual arguments associated with dummy data objects

If a scalar dummy argument is of type default character, the length len of the dummy argument shall be less than or equal to the length of the actual argument. The dummy argument becomes associated with the leftmost len characters of the actual argument.*'

module foo
contains
   function first(c)
      character(len=1), intent (in) :: c !< Means actual argument has len >= 1
      character(len=1) :: first
      first = c
   end function
end module foo

program anon
   use foo
   implicit none
   character(len=10) :: str
   str = 'ABCDEFGHIJ'
   print '('First character of ',a,' is ',a)', str, first(str)
end program anon
Please login to reply.