Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is there any need to nullify pointer before use?

944 views
Skip to first unread message

Mohammad

unread,
Jan 5, 2018, 1:43:48 AM1/5/18
to
The following fortran 2003 code uses some pointers without nullify them at the start. gfortran (8.0.0) issues segmentation fault:
(program received signal SIGSEGV: Segmentation fault - invalid memory reference.)

the same code under IVF (Intel visual fortran 18.0.1.156) produces correct results.

Does we need to nullify pointers before use? Is it a standard requirement?

Minimal code: a simple linked list

!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

program bad_associate_gfortran

type dyna
integer :: dat
type(dyna), pointer :: p
end type dyna

! local vars
type(dyna), pointer :: head, tail, ptr
integer :: i, ierr
! nullify(head, tail, ptr)

! set data
do i=1, 5
if (.not. associated(head) ) then
allocate(head, stat=ierr)
tail => head
nullify(tail%p)
tail%dat = i
else
allocate(tail%p, stat=ierr)
tail => tail%p
nullify(tail%p)
tail%dat=i
end if
end do

! print the data
ptr => head
do
if ( .not. associated(ptr) ) exit
print*, ptr%dat
ptr => ptr%p
end do


end program bad_associate_gfortran

!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Arjen Markus

unread,
Jan 5, 2018, 2:34:14 AM1/5/18
to
On Friday, January 5, 2018 at 7:43:48 AM UTC+1, Mohammad wrote:
> The following fortran 2003 code uses some pointers without nullify them at the start. gfortran (8.0.0) issues segmentation fault:
> (program received signal SIGSEGV: Segmentation fault - invalid memory reference.)
>
> the same code under IVF (Intel visual fortran 18.0.1.156) produces correct results.
>
> Does we need to nullify pointers before use? Is it a standard requirement?
>

The short answer is: yes.

The somewhat longer answer is that variables are not implicitly initialised. You can initialise them explicitly via statements like:

integer :: number = 0

(which has consequences for the storage that they take up - in this case: the variable number will implicitly get the SAVE attribute)

Or by simply setting the variable to some known value before using it:

number = 0

In some cases the uninitialised variable will have the value 0 but that is entirely coindicental and you should not rely on it. This is why your example fails with gfortran and "works" with Intel Fortran.

One exception to this rule is that allocatable variables are initialised to the status "allocated". This means you can inspect the status without explicitly having to allocate and later deallocate it. (In Fortran 95 the automatic deallocation of allocatable variables was introduced. A very nice form of garbage collection. I can imagine that the above exception is a consequence of this.)

But:
Even if pointers are automatically initialised (and I missed that rule) - or if variables in general are automatically initialised - it is good practice to explicitly initialise your variables.

Regards,

Arjen

Anton Shterenlikht

unread,
Jan 5, 2018, 6:52:00 AM1/5/18
to
Mohammad <mohammad...@gmail.com> writes:

>The following fortran 2003 code uses some pointers without nullify them at the start. gfortran (8.0.0) issues segmentation fault:
>(program received signal SIGSEGV: Segmentation fault - invalid memory reference.)

>the same code under IVF (Intel visual fortran 18.0.1.156) produces correct results.

>Does we need to nullify pointers before use? Is it a standard requirement?

>Minimal code: a simple linked list

>!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

> program bad_associate_gfortran
>
> type dyna
> integer :: dat
> type(dyna), pointer :: p
> end type dyna

>! local vars
> type(dyna), pointer :: head, tail, ptr
> integer :: i, ierr
>! nullify(head, tail, ptr)
>
>! set data
> do i=1, 5
> if (.not. associated(head) ) then

The f2003, and later, standards say for
ASSOCIATED (POINTER [,TARGET])

"POINTER ... Its pointer association status shall not be undefined."

So your program is not conforming.
Probably IVF quietly nullifies your
pointers at program start.
GCC probably leaves your pointers undefined.

Anton

Mohammad

unread,
Jan 5, 2018, 7:08:13 AM1/5/18
to
Thank you Arjen!

Mohammad

unread,
Jan 5, 2018, 7:10:42 AM1/5/18
to
Thank you!
It seems it best to nullify all pointers before use!

Steve Lionel

unread,
Jan 5, 2018, 12:35:28 PM1/5/18
to
On 1/5/2018 6:51 AM, Anton Shterenlikht wrote:
> Probably IVF quietly nullifies your
> pointers at program start.

No, it doesn't. Nor does it zero-initialize variables unless you ask for
that with a switch. (There is no switch to pre-nullify pointers.)

> GCC probably leaves your pointers undefined.

So does Intel Fortran. "Undefined" means that you can't depend on any
particular value. If that value ends up as zero due to something else,
that's not intentional on the part of the compiler.

--
Steve Lionel
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: http://intel.com/software/DrFortran

herrman...@gmail.com

unread,
Jan 5, 2018, 5:09:22 PM1/5/18
to
On Thursday, January 4, 2018 at 10:43:48 PM UTC-8, Mohammad wrote:
> The following fortran 2003 code uses some pointers without
> nullify them at the start.
(snip)

> if (.not. associated(head) ) then

In general, it isn't required. The majority of programs assign
to pointers, possibly with ALLOCATE, without problems.

But yes, if you test with ASSOCIATED(head) then head has to
either point to something or be null before use, and the
default doesn't do either one for you.

Ev. Drikos

unread,
Jan 6, 2018, 6:00:56 AM1/6/18
to
On 05/01/2018 13:51, Anton Shterenlikht wrote:
> ...
> GCC probably leaves your pointers undefined.
>
> Anton
>

Hi,

Just for the record, the above program runs smoothly in Darwin when
compiled with gfortran (i.e 7.1). Likely, this is platform specific
behavior.

Regards,
Ev. Drikos

Steve Lionel

unread,
Jan 6, 2018, 10:35:54 AM1/6/18
to
Or more likely, it's undefined and unpredictable behavior. As
programmers throughout the ages have learned the hard way, relying on
undefined behavior just because "it works" on one particular combination
of compiler and platform, doesn't mean that it will continue to work
forever or if the environment is changed.

Mohammad

unread,
Jan 6, 2018, 12:38:45 PM1/6/18
to
Yes, that's the best practice. Initialize variables (pointers) before use!

Ev. Drikos

unread,
Jan 6, 2018, 1:46:13 PM1/6/18
to
On 06/01/2018 19:38, Mohammad wrote:
> Yes, that's the best practice. Initialize variables (pointers) before use!

Without any doubt!

herrman...@gmail.com

unread,
Jan 6, 2018, 5:41:37 PM1/6/18
to
On Saturday, January 6, 2018 at 7:35:54 AM UTC-8, Steve Lionel wrote:
> On 1/6/2018 6:02 AM, Ev. Drikos wrote:

(snip)
> > Just for the record, the above program runs smoothly in Darwin when
> > compiled with gfortran (i.e 7.1). Likely, this is platform specific
> > behavior.

> Or more likely, it's undefined and unpredictable behavior. As
> programmers throughout the ages have learned the hard way, relying on
> undefined behavior just because "it works" on one particular combination
> of compiler and platform, doesn't mean that it will continue to work
> forever or if the environment is changed.

There are systems that reliably zero variables.

There are more that zero static variables but not automatic
variables.

I suspect that zero is most often unassociated for a pointer.

Unless you are sure that your program will only ever run on a system
that zeros the pointer, and that zero is unassociated, and that you
need to test assocation before use, you should nullify them.
(And, for that matter, appropriately initialize all other variables.)

spectrum

unread,
Jan 6, 2018, 7:05:25 PM1/6/18
to
Assuming that pointers in Fortran start from the "undefined" state upon declaration,

http://docs.cray.com/books/007-3692-003/html-007-3692-003/zfixediyw5tsqe.html
"The association status of a pointer can be defined or undefined; initially
(when a pointer is declared), it is undefined."

I'm wondering why this choice has been made in the Fortran standard...
In other words, why is it not good to initialize it to a null pointer (by the Standards)?

# This may be due to the same reason that other numeric variables in Fortran start
from undefined states (e.g., they are not initialized to 0 upon declaration).
I think this is understandable because the automatic initialization of a large array
to 0 may be simply a waste of time (if the user want to populate it with
different values immediately after declaration or allocation). Also, there is
some technique to initialize numeric variables with "NaN" to detect possible
bug (failure) for manual initialization. But.... these things seem to have nothing
with pointer initialization. It points to something or nothing, so I don't understand
why it is not initialized to the null pointer from the beginning...

FortranFan

unread,
Jan 6, 2018, 7:50:58 PM1/6/18
to
On Saturday, January 6, 2018 at 12:38:45 PM UTC-5, Mohammad wrote:

> ..
>
> Yes, that's the best practice. Initialize variables (pointers) before use!


Keeping in mind the dangers associated with the standard feature that arises out of "Explicit initialization of a variable that is not in a common block implies the SAVE attribute,"

note "If null-init appears, the initial association status of the object is disassociated."

But derived type components including pointers can have explicit initialization. So you can do:

!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
program p

type dyna
integer :: dat = 0
type(dyna), pointer :: p => null()
end type dyna

! local vars
type(dyna), pointer :: head => null()
type(dyna), pointer :: tail => null()
type(dyna), pointer :: ptr => null()
integer :: i, ierr

! set data
do i=1, 5
if (.not. associated(head) ) then
allocate(head, stat=ierr)
tail => head
tail%dat = i
else
allocate(tail%p, stat=ierr)
tail => tail%p
tail%dat=i
end if
end do

! print the data
ptr => head
do
if ( .not. associated(ptr) ) exit
print*, ptr%dat
ptr => ptr%p
end do


end program p


robin....@gmail.com

unread,
Jan 7, 2018, 12:59:12 AM1/7/18
to
All variables need to be initialized, either set to zero, or explicitly
in assignments to other specific constants, variables, and expressions,
or read in -- BEFORE they are used in any computation.

Any program that does not do this is in error. It cannot be assumed
that some compiler or other will initialize variables to zero.

herrman...@gmail.com

unread,
Jan 7, 2018, 1:31:00 AM1/7/18
to
On Saturday, January 6, 2018 at 4:05:25 PM UTC-8, spectrum wrote:
> Assuming that pointers in Fortran start from the
> "undefined" state upon declaration,

> http://docs.cray.com/books/007-3692-003/html-007-3692-003/zfixediyw5tsqe.html
> "The association status of a pointer can be defined or undefined; initially
> (when a pointer is declared), it is undefined."

> I'm wondering why this choice has been made in the Fortran standard...
> In other words, why is it not good to initialize it to a null
> pointer (by the Standards)?

Fortran has always done it that way.

Would it be hard to do differently?

C zeros all static data, but does nothing with automatic data.
Usually you get whatever was left on the stack. (The static might
be zero at the beginning, but then it changes as programs use it.)

C allows initializers on auto variables, which is sometimes
convenient.

Java zeros arrays when they are allocated (or false or null) but
for auto variables, the user is required to satisfy the compiler
that they are given a value before they are used. It is a compilation
error if the compiler can't be sure.

I suppose it wouldn't slow programs down so much to zero auto
variables each time.

robin....@gmail.com

unread,
Jan 7, 2018, 6:17:25 AM1/7/18
to
Scalar varables, no, but large arrays?

Ev. Drikos

unread,
Jan 7, 2018, 9:27:40 AM1/7/18
to
On 06/01/2018 13:02, Ev. Drikos wrote:
> On 05/01/2018 13:51, someone wrote:
>> ...
>> GCC probably leaves your pointers undefined.
>> ...
> Just for the record, the above program runs smoothly in Darwin when
> compiled with gfortran (i.e 7.1). Likely, this is platform specific
> behavior.
>

This is an explanation, not a suggestion.

> Regards,
> Ev. Drikos
>

jfh

unread,
Jan 7, 2018, 4:05:50 PM1/7/18
to
On Sunday, January 7, 2018 at 6:59:12 PM UTC+13, robin....@gmail.com wrote:
>
> All variables need to be initialized, either set to zero, or explicitly
> in assignments to other specific constants, variables, and expressions,
> or read in -- BEFORE they are used in any computation.
>
> Any program that does not do this is in error. It cannot be assumed
> that some compiler or other will initialize variables to zero.

Inquiry functions provide an exception. In this little program x is declared, not initialized, and used in a computation, but that's OK:

implicit none
real x
print *,log10(huge(x))
end program

spectrum

unread,
Jan 9, 2018, 2:28:30 PM1/9/18
to
Indeed, the basic idea for initialization seems very much different
among languages, and the choice may also depend on the goal of
a particular language (or due to hardware requiements at the time,
or other reasons...). I have looked at the Wiki page about Pointers (only
read some part of it yet):

https://en.wikipedia.org/wiki/Pointer_(computer_programming)

and one interesting sentence was in the Ada section:

https://en.wikipedia.org/wiki/Pointer_(computer_programming)#Ada

"Ada is a strongly typed language where all pointers are typed and only safe type conversions are permitted. All pointers are by default initialized to null, and any attempt to access data through a null pointer causes an exception to be raised."

> Scalar varables, no, but large arrays?

The efficiency can be a problem, but I also guess is there so many situations where
the declaration or allocation of huge number of pointers (e.g. contained in a linked lists or more complicated data structures) can cause peformance hit...?
Because it is initialization (not pointer assignment), it is done only once upon
declaration/definition, so maybe not much serious case? (I don,t know...)
If the cost is not a serious issue, I guess the initialization to null by default
may increase safety of the code.

robin....@gmail.com

unread,
Jan 10, 2018, 10:54:34 AM1/10/18
to
You're right. I overlooked that.
0 new messages