I used to be able to use code similar to:
program TstString implicit none ! Variables Character(7) :: String1 Character(15) :: String2 Integer(4) :: L ! Body of TstString String1 = "Check: " String2 = "True" L = LEN_TRIM(String2) Write(String2,"(A7,A5)") String1,String2(1:L) end program TstString
In the past the result was the string "Check: True "
Now I get "Check: Chec "
Apparently nowadays String1 is first written to String2 before both String1 and String2 are written to String2.
Is this intended behavior?
With best regards,
Steve may be able to answer why. My guess is use of String2 on both sides is undefined (implementation behavior)
To accomplish the same thing:
String2 = String1(1:7) // String2(1:5) ! concatenate sub-strings
My opinion is that this is a nonconforming program and the result is unpredictable. However, I can't find words in the standard that cover this, and will ask.
Section 18.104.22.168.1, rule 6 of the Fortran 2008 standard says:
If an internal file has been specified, an input/output list item shall not be in the file or associated with the file.
Thanks all for your support.
This approach has been in the code of one of our programs for appr. 15 years. I noticed that it didn't work anymore after recompiling with version 19.0.5.
I don't remember which was the last version I used for compiling the code that made it function as I intended.
Anyway introducing a conforming approach shouldn't be too difficult. I suppose the concatenation of sub-strings will do the job.
Steve Lionel (Ret.) (Blackbelt) wrote:
Yep - in F2018 that is 22.214.171.124.1p6
So, nonconforming, though compilers are not required to diagnose this. Results are unpredictable.
That's correct, from the "compiler's point of view". It is "by the book" after all.
However, let me humbly comment something here. It's not exactly the same from the "programmer's point of view". It would be nice if the compiler at least warned you of this (unpredictable) behavior. Unpredictable outcome can never be the developer's intention!
It would also help migrating such a program from an earlier intel fortran compiler, which used to yield different results. After all, to find and remedy such code you have no other choice but test-debug runs, which can be time consuming and tricky.
And it's not the best surprise to find after having upgraded to the brand new compiler!
>>It would also help migrating such a program from an earlier intel fortran compiler, which used to yield different results.
While this may be helpful in some cases, it is meaningless or even contra-helpful in other cases. In your specific case, you have a WRITE statement that is equivalent to a function call with an argument alias. This is forbidden (without attribute qualification). In this specific case, a "warn all" option (c/s)hould have issued a warning.
In different cases, for example where a poorly written convergence routine, produces drastically different results, you'd be asking the compiler to identify poorly written code.
It doesn't show any message with standards checking on.
As I wrote above, compilers aren't required to check this, though in this case it is possible and reasonable to do so.
So is standards checking in ifort meant to check only what the standards says it must check (do the standards even have such a requirement?) or is it meant to check (as much as is possible/practical) that the code is standard conforming to help users? I assumed the later which was the basis of the #8 comment.
The goal is to check as much as is feasible, with the minimum being what the standard requires. ifort goes way beyond that, as do most compilers, but there hasn't been a concerted effort to check each and every possible thing. It is worth raising this as a feature request to Support, as it's something easy to overlook in the implementation.
This is analagous to the problem of updating variables in programs, you create a dummy variable, string 3 and then set string 2 to string 3
i = 1
j = 2
let dum = j
j = i
i = j
In C programming you had memcpy and memmove. memcpy is undefined when strings overlap whereas memmove will check for overlap and adjust code accordingly. Fortran is just like memcpy (undefined).
C would not complain of overlapping strings.... because you may have expressly desired to duplicate a sub-string many times.