- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Hello,
the following code prints wrong results in the called subroutine:
module m
implicit none
contains
subroutine s(a, n)
integer, intent(in) :: n
class(*), intent(in) :: a(n)
select type(a)
type is(integer)
print *,'a is integer, a=', a
class default
print *,'a is unsupported type'
stop 1
end select
end
end
program p
use m
implicit none
integer :: b(2,2) = reshape([21, 22, 23, 24], [2,2])
print *,b
call s (b,4) ! OK
print *
print *,b(:,1::2)
call s (b(:,1::2),2) ! OK
print *
print *,b(1::2,:)
call s (b(1::2,:),2) ! bad
print *
print *,b(2::2,:)
call s (b(2::2,:),2) ! bad
end
I get with current ifort:
21 22 23 24
a is integer, a= 21 22 23 24
21 22
a is integer, a= 21 22
21 23
a is integer, a= 21 22
22 24
a is integer, a= 22 23
So while the first two cases are ok, the last two are not. Maybe there is no temporary generated for the passed array section to the explicit size dummy, and the actual stride of dimension 1 is not unity.
Thanks,
Harald
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I'm afraid that I'm on Harald's side here - there is no requirement that the dummy argument be assumed-shape. Sequence association does apply.
F2018 15.5.2.4
p18 Except when a procedure reference is elemental (15.8), each element of an array actual argument or of a sequence in a sequence association (15.5.2.11) is associated with the element of the dummy array that has the same position in array element order (9.5.3.2).
The compiler would have to do copy-in (and copy-out if not INTENT(IN) or a vector subscript.)
コピーされたリンク
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Thank you! Love these nice reproducers!
I'll check this out.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I filed a bug, CMPLRLLVM-45596. This reproducer gets the same wrong results with ifx.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
UPDATE... the compiler should actually print an error message.
Intel's resident Fortran standards guru told me:
The problem with the test case is that they are passing a two dimensional array section to a one dimensional explicit shape array. This is wrong because 1) passing an array section requires the dummy argument be assumed shape or deferred shape (bounds are declared with colons), and 2) because they are passing a two dimensional array to a one dimensional array and the interface is explicit.
If at line 6, the dimensions of a are declared as “a(:, :)”, it compiles fine an produces the output.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Would the resident Fortran standard guru please explain this?
For dummy arguments of intrisinc types, this works by F2018: 15.5.2.11 Sequence association. I do not see a reason for this to not apply here, so any helpful pointer is appreciated.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Here's an extended version that allows comparison of intrinsic type dummy and class(*) dummy:
module m
implicit none
contains
subroutine s(a, n)
integer, intent(in) :: n
class(*), intent(in) :: a(n)
select type(a)
type is(integer)
print *,'a is integer, a=', a
class default
print *,'a is unsupported type'
stop 1
end select
end
subroutine t(a, n)
integer, intent(in) :: n
integer, intent(in) :: a(n)
print *,'subroutine t: a=', a
end
end
program p
use m
implicit none
integer :: b(2,2) = reshape([21, 22, 23, 24], [2,2])
print *,b
call s (b,4) ! OK
call t (b,4) ! OK
print *
print *,b(:,1::2)
call s (b(:,1::2),2) ! OK
call t (b(:,1::2),2) ! OK
print *
print *,b(1::2,:)
call s (b(1::2,:),2) ! bad
call t (b(1::2,:),2) ! OK
print *
print *,b(2::2,:)
call s (b(2::2,:),2) ! bad
call t (b(2::2,:),2) ! OK
print *
print *, "With an explicit temporary:"
call s ((b(2::2,:)),2) ! this is now OK!
call t ((b(2::2,:)),2) ! also OK
end
So for the subroutine t with a dummy with explicit-shape array of type integer I get what I expect. With class(*) I'd need an explicit temporary.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I'm afraid that I'm on Harald's side here - there is no requirement that the dummy argument be assumed-shape. Sequence association does apply.
F2018 15.5.2.4
p18 Except when a procedure reference is elemental (15.8), each element of an array actual argument or of a sequence in a sequence association (15.5.2.11) is associated with the element of the dummy array that has the same position in array element order (9.5.3.2).
The compiler would have to do copy-in (and copy-out if not INTENT(IN) or a vector subscript.)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
After more research and discussion behind the scenes, the Fortran gurus determined that the original reproducer is valid code and Intel Fortran has a bug. Bug is filed as a runtime issue.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
It is not convincing this is a run-time issue only. The evidence is this is a combination issue with the compile-time actions toward the handling of unlimited polymorphic type with the explicit shape received argument. Because if you try with an integer type as opposed to unlimited polymorphic, you will see the program response is as expected by OP:
module m
contains
subroutine s(a, n)
integer, intent(in) :: n
integer, intent(in) :: a(n)
print *,'a is integer, a=', a
end
end
You many want to review this with the Intel Fortran team.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
@FortranFan, when I said "runtime issue" I meant that the compiler need not print an error message since the code is legal Fortran.
The compiler is indeed generating bad code for this case. That's the bug.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
With the release of 2024.0, both ifx and ifort are printing the correct answers at runtime.
Please check out the new releases.