<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Using QSORT routine with character strings in Intel® Fortran Compiler</title>
    <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757600#M13087</link>
    <description>I'm now passing the character lengths to the comparison subroutine via a public module variable, so this information now bypasses QSort. The arguments C1 and C2 to the comparison routine are then declared with this length. This seems to work and is a satisfactory solution for us.  It also no longer seems necessary to turn off bounds checking. Probably I was wrong in thinking bounds checking needed suppressing or it might have needed suppressing only because of the write(*,*) C1(1:70) which was deliberately looking outside the bounds to see what was happening.&lt;BR /&gt;&lt;BR /&gt;Thanks again for your help.&lt;BR /&gt;</description>
    <pubDate>Mon, 14 Sep 2009 18:18:40 GMT</pubDate>
    <dc:creator>nameiii</dc:creator>
    <dc:date>2009-09-14T18:18:40Z</dc:date>
    <item>
      <title>Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757593#M13080</link>
      <description>I'm having trouble using QSORT with character strings. On Compaq Fortran 6.6 (windows) the code below works but is not ideal because I need to know the string length in the comparison routine CharCIOrder. Attempts to apply Len direct to C1 or C2 cause "array bounds exceeded" on the following line (Len(C1)is equal to179523712) and attempts to apply Len_Trim to C1 or C2 cause "access violation" on the line with Len_Trim. Attempts to debug this crashes the developer studio. On Intel Fortran 9.1 (Linux) the code doesn't work. It gives a warning about copying the first argumentof QSORT_CHAR to a temp array and then fails with "memory fault" before leaving QSORT. Adding write statements shows the code enters the routine CharCIOrder but doesn't complete C1L=C1 and C2L=C2.&lt;BR /&gt; &lt;BR /&gt; Note that, in the case I've been running, MaxCharLength (defined in GlobalParametersModule) is 42, and Names is a 7 element array section.&lt;BR /&gt; &lt;BR /&gt; I'm new to passing routine names as arguments, so its quite likely I'm doing something wrong. Can anyone offer any advice?&lt;BR /&gt; &lt;BR /&gt; Many thanks&lt;BR /&gt; &lt;BR /&gt; Here's the code:&lt;BR /&gt; &lt;BR /&gt; Module SortModule&lt;BR /&gt; &lt;BR /&gt; USE DFPort ! Compaq&lt;BR /&gt; ! USE IFLPORT ! Intel&lt;BR /&gt; &lt;BR /&gt; Implicit None&lt;BR /&gt; &lt;BR /&gt; Private&lt;BR /&gt; Public :: SortInPlace&lt;BR /&gt; &lt;BR /&gt; Contains&lt;BR /&gt; &lt;BR /&gt; Subroutine SortInPlace(Names)&lt;BR /&gt; &lt;BR /&gt; Character(*) :: Names(:)&lt;BR /&gt; &lt;BR /&gt; Integer(2), External :: CharCIOrder&lt;BR /&gt; &lt;BR /&gt; Call QSort(Array = Names, Len = Size(Names), iSize = Len(Names(1)), Compar = CharCIOrder)&lt;BR /&gt; &lt;BR /&gt; End Subroutine SortInPlace&lt;BR /&gt; &lt;BR /&gt; End Module SortModule&lt;BR /&gt; &lt;BR /&gt; !-------------------------------------------------------------------------------------------------------------&lt;BR /&gt; &lt;BR /&gt; Function CharCIOrder(C1, C2)&lt;BR /&gt; ! Case insensitive order comparison.&lt;BR /&gt; &lt;BR /&gt; Use GlobalParametersModule&lt;BR /&gt; &lt;BR /&gt; Implicit None&lt;BR /&gt; ! Argument list:&lt;BR /&gt; Character(*), Intent(In) :: C1 !} Character strings to be compared.&lt;BR /&gt; Character(*), Intent(In) :: C2 !}&lt;BR /&gt; ! Function result: &lt;BR /&gt; Integer(2) :: CharCIOrder ! -1 if C1 before C2, 0 if C1 = C2, and 1 if C1 after C2.&lt;BR /&gt; ! Locals:&lt;BR /&gt; Character(MaxCharLength) :: C1L !} Local copies of C1 and C2.&lt;BR /&gt; Character(MaxCharLength) :: C2L !}&lt;BR /&gt; Integer :: i ! Loop index.&lt;BR /&gt; &lt;BR /&gt; C1L = C1&lt;BR /&gt; C2L = C2&lt;BR /&gt; &lt;BR /&gt; Do i = 1, Len_Trim(C1L)&lt;BR /&gt;  If ('a' &amp;lt;= C1L(i:i) .and. C1L(i:i) &amp;lt;= 'z') C1L(i:i) = Char(IChar(C1L(i:i)) - IChar('a') + IChar('A'))&lt;BR /&gt; End Do&lt;BR /&gt; Do i = 1, Len_Trim(C2L)&lt;BR /&gt;  If ('a' &amp;lt;= C2L(i:i) .and. C2L(i:i) &amp;lt;= 'z') C2L(i:i) = Char(IChar(C2L(i:i)) - IChar('a') + IChar('A'))&lt;BR /&gt; End Do&lt;BR /&gt; &lt;BR /&gt; If (C1L == C2L) Then&lt;BR /&gt;  CharCIOrder = 0&lt;BR /&gt; Else If (C1L &amp;lt; C2L) Then&lt;BR /&gt;  CharCIOrder = - 1&lt;BR /&gt; Else&lt;BR /&gt;  CharCIOrder = 1&lt;BR /&gt; End If&lt;BR /&gt; &lt;BR /&gt; End Function CharCIOrder&lt;BR /&gt; &lt;BR /&gt;</description>
      <pubDate>Sun, 02 Aug 2009 17:01:46 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757593#M13080</guid>
      <dc:creator>nameiii</dc:creator>
      <dc:date>2009-08-02T17:01:46Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757594#M13081</link>
      <description>Sorry - I should have added that "Names" is an array section of character strings each of length MaxCharLength (= 42) and the array section is contiguous. I.e.&lt;BR /&gt;&lt;BR /&gt; Character(MaxCharLength)         :: Names(2000)&lt;BR /&gt;&lt;BR /&gt;...&lt;BR /&gt;&lt;BR /&gt; Call SortInPlace(Names(1:7))&lt;BR /&gt;&lt;BR /&gt;Hopefully I haven't got array sections and character substrings muddled up, but I don't think I have! &lt;BR /&gt;&lt;BR /&gt;</description>
      <pubDate>Sun, 02 Aug 2009 17:53:38 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757594#M13081</guid>
      <dc:creator>nameiii</dc:creator>
      <dc:date>2009-08-02T17:53:38Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757595#M13082</link>
      <description>We have now reproduced the error in a much smaller code, so I can post the entire code and the result here. Hopefully someone might be able to help us. It appears that the character length isn't being passed correctly to the comparison routine, quite probably because we've done something wrong. &lt;BR /&gt;&lt;BR /&gt;Many thanks&lt;BR /&gt;&lt;BR /&gt;Here's the code:&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;program main&lt;BR /&gt;use IFLPort&lt;BR /&gt;implicit none&lt;BR /&gt;&lt;BR /&gt;character(10) :: c(7)&lt;BR /&gt;&lt;BR /&gt;Integer(2), External :: OrderCharCI ! Routine used to compute order of character strings.&lt;BR /&gt;&lt;BR /&gt;c(1)='aisjdop'&lt;BR /&gt;c(2)='35djf2'&lt;BR /&gt;c(3)='ss:ss'&lt;BR /&gt;c(4)='MMhQQ'&lt;BR /&gt;c(5)='mmHqq'&lt;BR /&gt;c(6)='aaaaa'&lt;BR /&gt;c(7)='["/'&lt;BR /&gt;&lt;BR /&gt;write(*,*) C&lt;BR /&gt;&lt;BR /&gt;Call QSort(C, Size(C), Len(C(1)), OrderCharCI)&lt;BR /&gt;&lt;BR /&gt;end program main&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;Function OrderCharCI(C1, C2)&lt;BR /&gt;! Computes order of character strings using a case insensitive ordering.&lt;BR /&gt;&lt;BR /&gt;Implicit None&lt;BR /&gt;! Argument list:&lt;BR /&gt;Character(*), Intent(In) :: C1 !} Character strings to be ordered.&lt;BR /&gt;Character(*), Intent(In) :: C2 !}&lt;BR /&gt;! Function result: &lt;BR /&gt;Integer(2) :: OrderCharCI ! -1 if C1 before C2, 0 if C1 = C2, and 1 if C1 after C2.&lt;BR /&gt;! Locals:&lt;BR /&gt;Character(10) :: C1L !} Local copies of C1 and C2.&lt;BR /&gt;Character(10) :: C2L !}&lt;BR /&gt;Integer :: i ! Loop index.&lt;BR /&gt;&lt;BR /&gt;write(*,*)'C1',len(C1)&lt;BR /&gt;write(*,*)'C1',C1(1:1)&lt;BR /&gt;write(*,*)'C1',C1(1:70)&lt;BR /&gt;&lt;BR /&gt;C1L = C1&lt;BR /&gt;C2L = C2&lt;BR /&gt;&lt;BR /&gt;! Note applying Len_Trim direct to C1 or C2 causes fatal error in Compaq Fortran&lt;BR /&gt;! - hence use of C1L, C2L. Undesirable because need to hard wire character length (10) &lt;BR /&gt;! (or pass by common block?)&lt;BR /&gt;! Attempting to debug in this routine causes fatal error in Compaq Fortran&lt;BR /&gt;! It doesn't work at all on Intel (Linux) Fortran - it fails with "memory fault" after &lt;BR /&gt;! start of routine but before getting to here.&lt;BR /&gt;&lt;BR /&gt;write(*,*) 'about to start do loop'&lt;BR /&gt;&lt;BR /&gt;Do i = 1, Len_Trim(C1L)&lt;BR /&gt; If ('a' &amp;lt;= C1L(i:i) .and. C1L(i:i) &amp;lt;= 'z') C1L(i:i) = Char(IChar(C1L(i:i)) - IChar('a') + IChar('A'))&lt;BR /&gt;End Do&lt;BR /&gt;Do i = 1, Len_Trim(C2L)&lt;BR /&gt; If ('a' &amp;lt;= C2L(i:i) .and. C2L(i:i) &amp;lt;= 'z') C2L(i:i) = Char(IChar(C2L(i:i)) - IChar('a') + IChar('A'))&lt;BR /&gt;End Do&lt;BR /&gt;&lt;BR /&gt;If (C1L == C2L) Then&lt;BR /&gt; OrderCharCI = 0&lt;BR /&gt;Else If (C1L &amp;lt; C2L) Then&lt;BR /&gt; OrderCharCI = - 1&lt;BR /&gt;Else&lt;BR /&gt; OrderCharCI = 1&lt;BR /&gt;End If&lt;BR /&gt;&lt;BR /&gt;End Function OrderCharCI&lt;BR /&gt;&lt;BR /&gt;and here's the result:&lt;BR /&gt;&lt;BR /&gt;$ ifort -V&lt;BR /&gt;Intel Fortran Compiler for 32-bit applications, Version 9.1 Build 20060927&lt;BR /&gt;Z Package ID: l_fc_c_9.1.039&lt;BR /&gt;Copyright (C) 1985-2006 Intel Corporation. All rights reserved.&lt;BR /&gt;&lt;BR /&gt;$ ifort -C -w -extend_source -nbs -Vaxlib -auto main.f90 -o sorttest.exe&lt;BR /&gt;$ sorttest.exe&lt;BR /&gt;aisjdop 35djf2 ss:ss MMhQQ mmHqq aaaaa ["/&lt;BR /&gt;C1 -1073746048&lt;BR /&gt;forrtl: severe (408): fort: (4): Variable C1 has substring ending point 1 which&lt;BR /&gt;is greater than the variable length of -1073746048&lt;BR /&gt;&lt;BR /&gt;Image PC Routine Line Source&lt;BR /&gt;sorttest.exe 080825D0 Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 0808149D Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 08062066 Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 0804ACE0 Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 080496D0 Unknown Unknown Unknown&lt;BR /&gt;libc.so.6 0049AA5A Unknown Unknown Unknown&lt;BR /&gt;libc.so.6 0049AA2B Unknown Unknown Unknown&lt;BR /&gt;libc.so.6 0049AA0D Unknown Unknown Unknown&lt;BR /&gt;libc.so.6 0049ACCC Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 08049CA1 Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 0804940A Unknown Unknown Unknown&lt;BR /&gt;libc.so.6 00485DE3 Unknown Unknown Unknown&lt;BR /&gt;sorttest.exe 08049341 Unknown Unknown Unknown&lt;BR /&gt;$ ifort -w -extend_source -nbs -Vaxlib -auto main.f90 -o sorttest.exe&lt;BR /&gt;$ sorttest.exe&lt;BR /&gt;aisjdop 35djf2 ss:ss MMhQQ mmHqq aaaaa ["/&lt;BR /&gt;C1 -1073746048&lt;BR /&gt;C13&lt;BR /&gt;C135djf2 ss:ss MMhQQ mmHqq aaaaa ["/ I&lt;BR /&gt;Memory fault&lt;BR /&gt;$&lt;BR /&gt;</description>
      <pubDate>Wed, 09 Sep 2009 12:54:27 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757595#M13082</guid>
      <dc:creator>nameiii</dc:creator>
      <dc:date>2009-09-09T12:54:27Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757596#M13083</link>
      <description>&lt;DIV style="margin:0px;"&gt;&lt;/DIV&gt;
nii.f90(20): error #6285: There is no matching specific subroutine for this generic subroutine call. [QSORT]&lt;BR /&gt;Call QSort(C, Size(C), Len(C(1)), OrderCharCI&lt;BR /&gt;i.e. there is no implementation of qsort provided for arrays of CHARACTER (at least not in my copy of ifport.f90)&lt;BR /&gt;</description>
      <pubDate>Wed, 09 Sep 2009 19:03:34 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757596#M13083</guid>
      <dc:creator>TimP</dc:creator>
      <dc:date>2009-09-09T19:03:34Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757597#M13084</link>
      <description>&lt;DIV style="margin:0px;"&gt;&lt;/DIV&gt;
&lt;BR /&gt;I do not know theinternals of how QSorthandles the character arguments and their associated lengths and I'm unable to find a working solution. I'll inquire with the library developer about this and post again when I know more.</description>
      <pubDate>Wed, 09 Sep 2009 19:04:56 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757597#M13084</guid>
      <dc:creator>Kevin_D_Intel</dc:creator>
      <dc:date>2009-09-09T19:04:56Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757598#M13085</link>
      <description>&lt;BR /&gt;Tim - the QSORT_CHAR interface is defined in ifport.f90 as far back as 8.1. Double check the declared types for the arguments or perhaps you compiled with -i8 (or similar)?&lt;BR /&gt;&lt;BR /&gt;Nameiii - Our Fortran RTL developers analyzed the case and found the issue relates to our QSORT implementation calling the ANSI system qsort (libc) which does not account for the character lengths for arguments C1 &amp;amp; C2 as you determined. They are continuing to investigate a resolution.&lt;BR /&gt;&lt;BR /&gt;As a work around, you could try using your defined parameter, MaxCharLength, inside OrderCharCI to declare C1 and C2 with CHARACTER(MaxCharLength) instead of CHARACTER(*). This will not work with the &lt;STRONG&gt;-C&lt;/STRONG&gt; (at least not the &lt;STRONG&gt;-check bounds&lt;/STRONG&gt; aspect), so you must avoid using at least bounds checking with this work around.&lt;BR /&gt;&lt;BR /&gt;I will update when I learn more.&lt;BR /&gt;&lt;BR /&gt;(Internal tracking id: DPD200139597)</description>
      <pubDate>Thu, 10 Sep 2009 10:33:26 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757598#M13085</guid>
      <dc:creator>Kevin_D_Intel</dc:creator>
      <dc:date>2009-09-10T10:33:26Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757599#M13086</link>
      <description>&lt;DIV style="margin:0px;"&gt;&lt;/DIV&gt;
Many thanks. Following your suggestion, declaring C1 &amp;amp; C2 as Character(10) (in the short example code) works. An alternative is to replace C1L = C1 etc by C1L = C1(1:10). Its slightly surprising that this works as C1L has length 10 and so I would not have expected the program to look beyond 1:10, even without this being specified. As you indicated, neither method works with the -C compilation option.&lt;BR /&gt;</description>
      <pubDate>Mon, 14 Sep 2009 10:15:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757599#M13086</guid>
      <dc:creator>nameiii</dc:creator>
      <dc:date>2009-09-14T10:15:00Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757600#M13087</link>
      <description>I'm now passing the character lengths to the comparison subroutine via a public module variable, so this information now bypasses QSort. The arguments C1 and C2 to the comparison routine are then declared with this length. This seems to work and is a satisfactory solution for us.  It also no longer seems necessary to turn off bounds checking. Probably I was wrong in thinking bounds checking needed suppressing or it might have needed suppressing only because of the write(*,*) C1(1:70) which was deliberately looking outside the bounds to see what was happening.&lt;BR /&gt;&lt;BR /&gt;Thanks again for your help.&lt;BR /&gt;</description>
      <pubDate>Mon, 14 Sep 2009 18:18:40 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757600#M13087</guid>
      <dc:creator>nameiii</dc:creator>
      <dc:date>2009-09-14T18:18:40Z</dc:date>
    </item>
    <item>
      <title>Re: Using QSORT routine with character strings</title>
      <link>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757601#M13088</link>
      <description>&lt;DIV style="margin:0px;"&gt;&lt;/DIV&gt;
Appreciate the updates on the additional alternatives. Those could prove useful for others too. I'm glad you found satisfactory solution.&lt;BR /&gt;</description>
      <pubDate>Mon, 14 Sep 2009 19:06:12 GMT</pubDate>
      <guid>https://community.intel.com/t5/Intel-Fortran-Compiler/Using-QSORT-routine-with-character-strings/m-p/757601#M13088</guid>
      <dc:creator>Kevin_D_Intel</dc:creator>
      <dc:date>2009-09-14T19:06:12Z</dc:date>
    </item>
  </channel>
</rss>

