- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since upgrading to OneApi 2023.2 and Visual Studio Professional 2022 (64-bit) - LTSC 17.6 I have some existing code when try something along the following line:
s1=s2
where s1 and s2 are a Type containing among standard types (various fixed size array of real, integers) a variable defined as : character(len=:), allocatable :: mydata
One way I got it to NOT crash was to define an assignment procedure:
procedure, private, pass(sin) :: assign_ MyType
generic, public :: assignment(=) => assign_ MyType
inside which I have this code
! only copy the allocatable character if allocated
if(allocated(sin%fname)) then
sout%mydata= sin%mydata
endif
This seems to have fixed the crash but I wanted to know if it was a known issue or just luck as I cannot reproduce it with a simple example.
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Clearly I should have written this message more carefully.
What I meant is that WITHOUT the explicit assignment procedure it crashes.
I was wondering if anyone had issues copying unallocated array of characters ?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not had problems like this with the compiler recently.
Your follow up post asks about array of characters, your original post describes a scalar character component. Neither as components should require the defined assignment.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following reproducer shows similar behavior (unexpected)
! AssignEmptyArray.f90
program AssignEmptyArray
implicit none
real, allocatable :: OutputArray(:), InputArray(:), EmptyArray(:)
allocate(InputArray(100))
print *, size(OutputArray)
OutputArray = InputArray
print *, size(OutputArray)
OutputArray = EmptyArray
print *, size(OutputArray)
end program AssignEmptyArray
...
0
100
100
The expected result for the last print statement would be 0.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Additional info.
! AssignEmptyArray.f90
program AssignEmptyArray
implicit none
real, allocatable :: OutputArray(:), InputArray(:), EmptyArray(:)
allocate(InputArray(100))
print *, size(OutputArray)
OutputArray = InputArray
print *, size(OutputArray)
OutputArray = EmptyArray
print *, size(OutputArray)
allocate(EmptyArray(0))
OutputArray = EmptyArray
print *, size(OutputArray)
end program AssignEmptyArray
...
0
100
100
0
Apparently there is a difference between:
Never been allocated allocatable array
and
Allocated to empty allocatable array
Perhaps on your user defined type initialization code, you could allocate a zero length character variable (and in place of, or in addition to, using ...allocated(variable), you test for length of 0 or all spaces).
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In F2008 (haven't checked 2018) It says the argument of SIZE "shall not be an unallocated allocatable variable" thus the code is not valid so the answer is undefined. use of if ( allocated(thing)) is my recommendation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please explain and illustrate the problem you face with suitable details including what you mean by "crash". Preferably you will share with the Intel team and the readers here your specific error scenario.
If for any reason (e.g., proprietary codebase?) you can't do so, take the following which does NOT reveal any issue with Intel oneAPI 2023.2.0 but then adapt it to demonstrate the problem.
type :: t
integer :: n = 0
character(len=:), allocatable :: s
end type
type(t) :: a, b
a%n = 42
b = a
print *, "b%n = ", b%n, "; expected is ", a%n
print *, "allocated(b%s)? ", allocated(b%s), "; expected is F"
end
C:\temp>ifort /free /standard-semantics p.f
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:p.exe
-subsystem:console
p.obj
C:\temp>p.exe
b%n = 42 ; expected is 42
allocated(b%s)? F ; expected is F
C:\temp>ifx /free /standard-semantics p.f
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.2.0 Build 20230627
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.36.32537.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:p.exe
-subsystem:console
p.obj
C:\temp>p.exe
b%n = 42 ; expected is 42
allocated(b%s)? F ; expected is F
C:\temp>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all, thanks.
One of the issue i have is that i cannot create a simple type that caused the issue when compiled alone.
This is my type:
module Test
type::tType
integer :: rec1(20) = 0
integer :: rec2(8) = 0
integer :: rec3_a(10,6) = 0
integer :: rec3_b(10,2) = 0
integer :: rec4_a(5) = 0
real :: rec4_b(2) = 0.0
integer :: rec4_c = 0
integer :: rec5(6) = 0
integer :: rec6 = 0
real :: rec7(4) = 0.0
integer :: rec8_a = 0
character(len=256) :: rec8_b = ''
integer :: rec9(3) = 0
integer :: nrecords = 9
character(len=:), allocatable :: fname
end type tType
end module Test
used as like this
program Console1
use Test
implicit none
! Variables
type(tType) :: t1,t2
! Body of Console1
print *, 'copy type'
!if(allocated(t1%fname)) then
t1=t2
end program Console1
The example above will NOT crash in a simple program but will crash (at t1=t2) within a more complex program.
@jimdempseyatthecove I am not sure i understand your suggestion
"Perhaps on your user defined type initialization code, you could allocate a zero length character variable (and in place of, or in addition to, using ...allocated(variable), you test for length of 0 or all spaces).
"
What would this look like for your example ?
Thanks and regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There have been compiler bugs in this area historically, but equally what you describe could be due to memory corruption from a separate erroneous part of your code. A typical approach to isolate the cause of the problem (and/or generate a minimum example for a compiler bug report is to progressively cut your program down - a "binary chop" approach or similar. For large code bases I have sometimes spent a day or two doing this, which is costly, but ultimately both necessary and worth it.
Alternatively, using the debugger you may be able to determine what it is that is causing the program to crash at the time it crashes (e.g. the descriptor for the allocatable character scalar component has become corrupted in some way). If the crash is relatively reproducible you can then set data breakpoints on the relevant parts of the descriptor to see which bit of wayward code is causing the corruption, when you run it for a second time (at least...) in the debugger.
At this stage I would concentrate more on identifying the cause than implementing a work around. If the cause is a fault in your code - you want it fixed. If the cause is a fault in the compiler you (and the rest of us!) also want it fixed - that will take longer, but while waiting for a fix you will want to understand the implications.
(There are lots of explicit shape array components in that derived type... run off the end of those and chaos will result...)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm, well this is interesting:
module Test
type::tType
integer :: rec1(20) = 0
integer :: rec2(8) = 0
integer :: rec3_a(10,6) = 0
integer :: rec3_b(10,2) = 0
integer :: rec4_a(5) = 0
real :: rec4_b(2) = 0.0
integer :: rec4_c = 0
integer :: rec5(6) = 0
integer :: rec6 = 0
real :: rec7(4) = 0.0
integer :: rec8_a = 0
character(len=256) :: rec8_b = ''
integer :: rec9(3) = 0
integer :: nrecords = 9
character(len=:), allocatable :: fname
end type tType
end module Test
program Console1
use Test
implicit none
character(len=0) :: empty
type(tType) :: t1, t2
t2%fname = empty
print *, 'copy type'
!if(allocated(t1%fname)) then
t1=t2
end program Console1
**** place break point on print (line 27) ****
Notes:
The above was ifort, 32-bit build
Note variable EMPTY is CHARACTER(0)
t1%fname, which was not expressly allocated, nor assigned to (aka defined), is a character variable of len=4 containing ' '
t2%fname, which was not expressly allocated, but assigned to (aka defined) a character variable who's len=0, results in a character variable who's len=4 and contains junk data.
Note, prior to t2%fname = empty, t2%fname contained a character variable of len=4 containing ' '
On ifort, 64-bit build, same situation except the before t2%fname = empty, t1 and t2 fname is a character variable of len=8 containing ' '
ifx, x64-bit build
Variable EMPTY appears as "undefined pointer/array" of type CHARACTER(*)
(ifort correctly had this as a defined ('') of type CHARACTER(0) )
After the assignment (t2%fname = empty), fname becomes defined as 'junkjunk', an eight character CHARACTER(*) variable.
Some weird behavior going on.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program Console1
implicit none
character(len=0) :: empty
character(len=:), allocatable :: t1, t2
t2 = empty
print *, 'copy type'
t1 = t2
end program Console1
The behaviour @jimdempseyatthecove describes is not related to derived types as the above program behaves in the same way in the debugger.
EDIT but maybe that is some debugger integration quirk as print *, 'copy type', len(t2), sizeof(t2) generates 0 (zero) in both cases.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Andrew,
I could not get the sample program to fail (OP mentioned simple reproducer did not show symptoms).
My post, was an attempt to construct a work around. And in the process, noted peculiarities (?bugs?,?undefined behavior?) as noted in the debug session.
character(len=0) :: empty
ifort shows the expected '' character(0) variable. IOW a character variable of len=0
ifx shows unexpectedly undefined pointer/array character(*). I presume this is a bug.
ifx, character(len=:), allocatable :: t1, t2
Prior to being defined, shows the len=4 with blanks.
*** However, inserting print *,len(t2%fname) does show len=0 ***
Therefore the Debugger integration seems incorrect whereas the runtime len(...) returns the correct/expected length
It testing the t1=t2, at least on my system, the code produces the expected results.
On my system, v 2023.1, it would seem
IF(LEN(T2%FNAME)==0) ...
Would be a suitable test for an unallocated, character(len=:) variable.
IOW this does not error/crash. As to if this will hold true for future versions, I cannot say.
Additional side note:
program Console1
use Test
implicit none
character(len=0) :: empty
type(tType) :: t1, t2
print *, len(t2%fname), allocated(t2%fname)
t1=t2
print *, len(t1%fname), allocated(t1%fname)
t2%fname = '123456789'
print *, len(t2%fname), allocated(t2%fname)
t1=t2
print *, len(t1%fname), allocated(t1%fname)
t2%fname = empty
print *, len(t2%fname), allocated(t2%fname)
t1=t2
print *, len(t1%fname), allocated(t1%fname)
deallocate(t2%fname)
print *, len(t2%fname), allocated(t2%fname)
t1=t2
print *, len(t1%fname), allocated(t1%fname)
end program Console1
shows
0 F
0 F
9 T
9 T
0 T
0 T
0 F
0 F
The execution is correct (as expected).
There must be some other nuance with your failing code that is not expressed in your failing (crashing) code.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear All, many thanks. I ll update you when i found out where it is going wrong.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page