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

gfortran -Wmaybe-uninitialized array descriptor?

870 views
Skip to first unread message

Sebastien Bardeau

unread,
Nov 26, 2013, 8:55:27 AM11/26/13
to
Dear gfortran gurus,

I am trying to fix the "uninitialized warnings" found in my code, and I
can not get rid of the following one (see below).

Those warnings seem to be very touchy, I could not shorten more my
example. Note that I use the flag "-Wuninitialized" while gfortran
returns "-Wmaybe-uninitialized" warnings.

So, what does gfortran is warning me about? Is there a syntax that I
could use to satisfy it? Usually adding a variable initialization or a
missing "else" block is enough, but here I could not find.

Any help?

Thank you,

Sebastien



$ cat map-xymap.f90
subroutine table_to_cube_data(nx,ny,gweight)
integer(kind=4), intent(in) :: nx
integer(kind=4), intent(in) :: ny
real(kind=4), intent(in) :: gweight(nx,ny)
! Global
logical, external :: failed_allocate
! Local
real(kind=4), allocatable :: raw(:,:)
integer(kind=4) :: iy,ier
!
allocate(raw(nx,ny),stat=ier)
if (failed_allocate('table_to_cube_data','raw array',ier)) return
!
do iy=1,ny
if (gweight(1,iy).gt.0.0) then
raw(1,iy) = -1000.0
endif
enddo
!
end subroutine table_to_cube_data

$ gfortran --version
GNU Fortran (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.

GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING


$ gfortran -c -Wuninitialized -O map-xymap.f90 -o map-xymap.o
map-xymap.f90: In function �table_to_cube_data�:
map-xymap.f90:16:0: warning: �raw.offset� may be used uninitialized in
this function [-Wmaybe-uninitialized]
raw(1,iy) = -1000.0
^
map-xymap.f90:16:0: warning: �raw.dim[1].stride� may be used
uninitialized in this function [-Wmaybe-uninitialized]

\"Vladimír Fuka <"name.surnameat

unread,
Nov 26, 2013, 9:15:00 AM11/26/13
to

Richard Maine

unread,
Nov 26, 2013, 11:00:51 AM11/26/13
to
Sebastien Bardeau <bar...@no.domain> wrote:

> I am trying to fix the "uninitialized warnings" found in my code, and I
> can not get rid of the following one (see below).
>
> Those warnings seem to be very touchy, I could not shorten more my
> example. Note that I use the flag "-Wuninitialized" while gfortran
> returns "-Wmaybe-uninitialized" warnings.
>
> So, what does gfortran is warning me about? Is there a syntax that I
> could use to satisfy it? Usually adding a variable initialization or a
> missing "else" block is enough, but here I could not find.
[code elided]

I didn't try to verify the problem, but I don't see anything wrong with
the code as shown. Heck, the variable it warns about isn't used at all,
much less used when not "initialized".

Seems more like a quirk in gFortran's warning than a real problem.

I advise against adding code contortions that have no purpose other than
to work around warnings. That's particularly the case when the warnings
are bogus and come from only one particular compiler. If you go down
that path, your code can become full of cruft as you add workarounds for
multiple compilers. You might even find that the workarounds for one
compiler cause warnings for another.

A case of this kind of thing that I find particularly disconcerting is
when people take perfectly safe and standard-conforming code that
generates a warning, but they add a workaround fo rthe warning that can
actually make the code non-standard, but avoids the warning. I've seen
this in particular about "unused dummy argument" warnings. It can be
perfectly fine to have dummy arguments that are unused; it is natural
and common in some contexts (such as writing a particular case of a
subroutine that doesn't need all the data that the caling program
provides). Common "fixes" for this warning involve adding a spurious
reference to the variable, which has the potential of being an actual
error if the variable is undefined (which the subroutine can't know in
general). Workarounds to that error to make sure that the reference is
never actually executed can in turn cause different warnings with other
compilers. That's why I like compilers to have the capability to turn
off that particular warning, so that the numerous cases of it don't hide
warnings that I might actually care about.

I definitely encourage making sure to understand what warnings are
about, as you appear to be doing in your question here. Looks like it
might be warning either about the fact that some elements of the array
are undefined depending on the value of gweight, or that some elements
are never defined (all those in rows other than 1). But as long as you
never reference the potentially undefined elements, that's ok.

If the warning points to an actual problem, then certainly fix it, but I
wouldn't hack the code just to silence the warning.

As an aside, let me note that, independent of the question of whether
the warning is appropriate or not for this particulat case, I regard the
wording of the warning, and indeed even the switch name, as a compiler
bug that can cause confusion. The term "initialized" has a specific
technical meaning in Fortran, and it is the wrong term for this warning.
There is *NO* problem with using a variable that has not been
initialized. I cannot think of a single place where the standard
requires that a variable be initialized. Most variables in Fortran
programs are not initialized. There are many variables that it is not
even possible to initialize. What *IS* a problem is referencing a
variable that is undefined. Initialization is one way of making a
variable defined. But it is far from the only way or even the most
common way. Furthermore, even if a variable is initialized, it can later
become undefined.

People get confused enough anyway by what it means for a variable to be
undefined. I'm not sure whether whoever wrote that warning message was
confused themselves, or whether they thought that using different
terminology would help clarify things for users. If they thought it
would help clarify things, then I have to vehemently disagree. Maybe
that might work if you managed to come up with some other term that was
intuitive and wasn't otherwise used in the Fortran standard, I might buy
it. I can't offhand think of such a term, but I didn't try very hard,
and I grant the possibility that one might come up with such a thing.
But to use a term ("initialized") that does have meaning in Fortran, and
use it for something that is different from the meaning in the standard
strikes me as a way to add confusion rather than a way to avoid it.
That's even more so because the terms in question do have at least some
relationship - enough that someone might actually believe that the
message means what it says.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

Steven G. Kargl

unread,
Nov 26, 2013, 11:20:46 AM11/26/13
to
On Tue, 26 Nov 2013 14:55:27 +0100, Sebastien Bardeau wrote:

> I am trying to fix the "uninitialized warnings" found in my code, and I
> can not get rid of the following one (see below).

(code deleted)

> $ gfortran -c -Wuninitialized -O map-xymap.f90 -o map-xymap.o
> map-xymap.f90: In function ‘table_to_cube_data’:
> map-xymap.f90:16:0: warning: ‘raw.offset’ may be used uninitialized in
> this function [-Wmaybe-uninitialized]
> raw(1,iy) = -1000.0
> ^
> map-xymap.f90:16:0: warning: ‘raw.dim[1].stride’ may be used
> uninitialized in this function [-Wmaybe-uninitialized]

You can get rid of the useless warning in 3 different ways.

1) Do not use -O when compling.
2) Remove stat=ier from the allocate statement.
3) Ignore the useless warnings as gfortran is clearly complaining about
internally generated entities.

--
steve

Steven G. Kargl

unread,
Nov 26, 2013, 11:48:41 AM11/26/13
to
On Tue, 26 Nov 2013 08:00:51 -0800, Richard Maine wrote:
>
> People get confused enough anyway by what it means for a variable to be
> undefined. I'm not sure whether whoever wrote that warning message was
> confused themselves, or whether they thought that using different
> terminology would help clarify things for users. If they thought it
> would help clarify things, then I have to vehemently disagree. Maybe
> that might work if you managed to come up with some other term that was
> intuitive and wasn't otherwise used in the Fortran standard, I might buy
> it. I can't offhand think of such a term, but I didn't try very hard,
> and I grant the possibility that one might come up with such a thing.
> But to use a term ("initialized") that does have meaning in Fortran, and
> use it for something that is different from the meaning in the standard
> strikes me as a way to add confusion rather than a way to avoid it.
> That's even more so because the terms in question do have at least some
> relationship - enough that someone might actually believe that the
> message means what it says.

That particular warning is coming from GCC's middle-end. The middle-end
is, of course, used by all language front-ends. These can include C, C++,
Objective C, java, Fortran, ada, go, and others. Whether all language
standards use the same terminology to described uninitialized or undefined
variables is left as an exercise for the reader.

Given that gfortran was bolted onto a 20(?) year-old GCC infrastructure,
and given that gfortran is a bit player in GCC's overall scheme, and given
the diminishing number of contributors, go luck in getting the language of
the warning changed.

--
steve


glen herrmannsfeldt

unread,
Nov 26, 2013, 12:17:46 PM11/26/13
to
Richard Maine <nos...@see.signature> wrote:
> Sebastien Bardeau <bar...@no.domain> wrote:

>> I am trying to fix the "uninitialized warnings" found in my code,
>> and I can not get rid of the following one (see below).

(snip)
> [code elided]

> I didn't try to verify the problem, but I don't see anything wrong with
> the code as shown. Heck, the variable it warns about isn't used at all,
> much less used when not "initialized".

> Seems more like a quirk in gFortran's warning than a real problem.

> I advise against adding code contortions that have no purpose other than
> to work around warnings. That's particularly the case when the warnings
> are bogus and come from only one particular compiler. If you go down
> that path, your code can become full of cruft as you add workarounds for
> multiple compilers. You might even find that the workarounds for one
> compiler cause warnings for another.

Seems that there are some organizations that require all programs
written to compile without warnings. For the reasons that you note,
that does not seem like a good idea to me. Some might have a specific
set of warnings, which might not be so bad, but there seems to be a
tendency to add more warnings to compilers, even when it is less and
less obvious that they are a good idea.

> A case of this kind of thing that I find particularly disconcerting is
> when people take perfectly safe and standard-conforming code that
> generates a warning, but they add a workaround fo rthe warning that can
> actually make the code non-standard, but avoids the warning. I've seen
> this in particular about "unused dummy argument" warnings. It can be
> perfectly fine to have dummy arguments that are unused; it is natural
> and common in some contexts (such as writing a particular case of a
> subroutine that doesn't need all the data that the caling program
> provides). Common "fixes" for this warning involve adding a spurious
> reference to the variable, which has the potential of being an actual
> error if the variable is undefined (which the subroutine can't know in
> general). Workarounds to that error to make sure that the reference is
> never actually executed can in turn cause different warnings with other
> compilers. That's why I like compilers to have the capability to turn
> off that particular warning, so that the numerous cases of it don't hide
> warnings that I might actually care about.

Some are nice to have once in a while. The lint program for C used to
do some checks that compilers didn't do, and that one might like to
have as a final check before releasing, or otherwise believing in the
results of a program.

> I definitely encourage making sure to understand what warnings are
> about, as you appear to be doing in your question here. Looks like it
> might be warning either about the fact that some elements of the array
> are undefined depending on the value of gweight, or that some elements
> are never defined (all those in rows other than 1). But as long as you
> never reference the potentially undefined elements, that's ok.

> If the warning points to an actual problem, then certainly fix it, but I
> wouldn't hack the code just to silence the warning.

> As an aside, let me note that, independent of the question of whether
> the warning is appropriate or not for this particulat case, I regard the
> wording of the warning, and indeed even the switch name, as a compiler
> bug that can cause confusion. The term "initialized" has a specific
> technical meaning in Fortran, and it is the wrong term for this warning.
> There is *NO* problem with using a variable that has not been
> initialized. I cannot think of a single place where the standard
> requires that a variable be initialized. Most variables in Fortran
> programs are not initialized. There are many variables that it is not
> even possible to initialize. What *IS* a problem is referencing a
> variable that is undefined. Initialization is one way of making a
> variable defined. But it is far from the only way or even the most
> common way. Furthermore, even if a variable is initialized, it can later
> become undefined.

As there is much code in common between gfortran and the gcc compilers
for other languages, and some of these warnings may come in later parts
of the compilation, it is possible that the warning isn't Fortran
specific.

Even more, while there are ways for variables to become undefined, it is
likely even harder for compilers to figure that out than to figure out
that one has been given a value before it is used.

> People get confused enough anyway by what it means for a variable to be
> undefined. I'm not sure whether whoever wrote that warning message was
> confused themselves, or whether they thought that using different
> terminology would help clarify things for users. If they thought it
> would help clarify things, then I have to vehemently disagree. Maybe
> that might work if you managed to come up with some other term that was
> intuitive and wasn't otherwise used in the Fortran standard, I might buy
> it. I can't offhand think of such a term, but I didn't try very hard,
> and I grant the possibility that one might come up with such a thing.
> But to use a term ("initialized") that does have meaning in Fortran, and
> use it for something that is different from the meaning in the standard
> strikes me as a way to add confusion rather than a way to avoid it.
> That's even more so because the terms in question do have at least some
> relationship - enough that someone might actually believe that the
> message means what it says.

Would be intersting to know if the parts of gfortran that are common to
compilation of different languages can generate language specific errors
and warnings.

-- glen

Richard Maine

unread,
Nov 26, 2013, 12:31:45 PM11/26/13
to
Steven G. Kargl <s...@REMOVEtroutmask.apl.washington.edu> wrote:

> On Tue, 26 Nov 2013 08:00:51 -0800, Richard Maine wrote:
> >
> > [gripes about misuse of the term "uninitialized" in gFortran's warnings]

> That particular warning is coming from GCC's middle-end. The middle-end
> is, of course, used by all language front-ends. These can include C, C++,
> Objective C, java, Fortran, ada, go, and others. Whether all language
> standards use the same terminology to described uninitialized or undefined
> variables is left as an exercise for the reader.
>
> Given that gfortran was bolted onto a 20(?) year-old GCC infrastructure,
> and given that gfortran is a bit player in GCC's overall scheme, and given
> the diminishing number of contributors, go luck in getting the language of
> the warning changed.

Point taken. Guess I'm sensitive (oversensitive?) to the issue because I
occasionally see people get confused about the distinctions and actually
think that there is some requirement for variables to be initialized (in
the Fortran standard sense).

Steven G. Kargl

unread,
Nov 26, 2013, 1:47:51 PM11/26/13
to
FWIW, I have a healthy dislike for this warning as well as -Wconversion,
because they are too noisy. When debugging with gfortran I typically
use "-fmax-errors=1 -Werror -Wall -fcheck=all" where I often need to
add -Wno-conversion and -Wno-uninitialized.

There is a mechanism in place for marking an entity as used (which
means defined or initialized) in a language front-end, which will silence
the middle-end. I've never been able to track down where this
treatment is needed.

--
steve

Sebastien Bardeau

unread,
Nov 29, 2013, 11:08:50 AM11/29/13
to
Dear Steven,

On 11/26/2013 05:20 PM, Steven G. Kargl wrote:

> You can get rid of the useless warning in 3 different ways.
>
> 1) Do not use -O when compling.

Well, I won't turn off this flag because 1) I do want to use it here and
everywhere else in my code, and 2) it is supposed to provide safe
optimizations, which seems (naively for me basic (g)Fortran user)
unrelated to the current topic.


> 2) Remove stat=ier from the allocate statement.

But I do want to check if the allocation is successful or not. No
purpose to continue if the array could not be allocated.


> 3) Ignore the useless warnings as gfortran is clearly complaining about
> internally generated entities.

It seems I will pick up this one, since now I know those warnings are
not directly related to my program.

I can understand what you explained to Richard ("Given that gfortran was
bolted onto a 20(?) year-old GCC infrastructure..."), but should I file
in a bug report? Or maybe I should just wait for this one to be fixed:
gcc.gnu.org/bugzilla/show_bug.cgi?id=58410

Thank you,

Sebastien

Sebastien Bardeau

unread,
Nov 29, 2013, 11:16:46 AM11/29/13
to
Thank you Richard for those detailed considerations about variable
initialization and referencing. I hope I have a correct understanding of
these "concepts", but I was just disconcerted by these gfortran
warnings. And given Steven explanations, this was perfectly normal ;-)

JB

unread,
Nov 29, 2013, 4:41:35 PM11/29/13
to
On 2013-11-29, Sebastien Bardeau <bar...@no.domain> wrote:
>> 2) Remove stat=ier from the allocate statement.
>
> But I do want to check if the allocation is successful or not. No
> purpose to continue if the array could not be allocated.

The Fortran standard requires that if the allocation fails and stat=
is not present, then the program is terminated. Using stat= is useful
mostly in cases where you have some more sophisticated way of dealing
with allocation failures than printing an error message and
terminating the program (i.e. first deallocate some cached data, or
retry the allocation with a smaller size, etc.).

That being said, since many operating systems tend to overcommit
memory, you might see that the allocation itself succeeds, but then
when enough pages are faulted in the program is killed.


--
JB

ftin...@gmail.com

unread,
Nov 29, 2013, 4:50:52 PM11/29/13
to
I've seen/enjoyed... this and I usually analyze memory requirements
and/or check before "getting" more memory than that the OS can
"safely" handle.

Fernando.

glen herrmannsfeldt

unread,
Nov 29, 2013, 6:04:53 PM11/29/13
to
Sebastien Bardeau <bar...@no.domain> wrote:

> On 11/26/2013 05:20 PM, Steven G. Kargl wrote:

(snip)

>> 2) Remove stat=ier from the allocate statement.

> But I do want to check if the allocation is successful or not. No
> purpose to continue if the array could not be allocated.

From the OP, you have:

allocate(raw(nx,ny),stat=ier)
if (failed_allocate('table_to_cube_data','raw array',ier)) return

it might be that the compiler would figure out:

allocate(raw(nx,ny),stat=ier)
if(ier.ne.0) return

but there is no way the compiler can know that failed_allocate always
returns true when the allocation fails. The complier has to assume
that the allocation could fail, and still reach statements using raw.

You might try:

allocate(raw(nx,ny),stat=ier)
if (failed_allocate('table_to_cube_data','raw array',ier).or.ier.ne.0) return

though I wouldn't be surprised if it still didn't avoid the problem.

-- glen


robin....@gmail.com

unread,
Nov 29, 2013, 6:38:42 PM11/29/13
to
On Saturday, November 30, 2013 8:41:35 AM UTC+11, JB wrote:
> On 2013-11-29, Sebastien Bardeau <b...@no.domain> wrote: >> 2) Remove stat=ier from the allocate statement. > > But I do want to check if the allocation is successful or not. No > purpose to continue if the array could not be allocated. The Fortran standard requires that if the allocation fails and stat= is not present, then the program is terminated. Using stat= is useful mostly in cases where you have some more sophisticated way of dealing with allocation failures than printing an error message and terminating the program (i.e. first deallocate some cached data, or retry the allocation with a smaller size, etc.).

Perhaps. Or just to write out a nice error message with an explanation
of where the error occurred, and why.

Richard Maine

unread,
Nov 30, 2013, 9:31:54 AM11/30/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> You might try:
>
> allocate(raw(nx,ny),stat=ier)
> if (failed_allocate('table_to_cube_data','raw array',ier).or.ier.ne.0)
return

That's a good example of the kind of thing I said I recommended against.
It's a hack with no purpose other than to (possibly) avoid a spurious
compiler warning from a particular compiler and it makes the code
confusing.

Were it not in this thread, I'd look at that and wonder what in the heck
failed_allocate was checking. It sure would not occur to me that
failed_allocate would always return the same value as the redundant
ier.ne.0 test.

paul.rich...@gmail.com

unread,
Nov 30, 2013, 3:34:00 PM11/30/13
to
On Tuesday, 26 November 2013 15:15:00 UTC+1, \"Vladimír Fuka <\"name.surname at wrote:
> Reminds me this bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58410

Hi Vladimir,

I just posted a fix for PR58410. It turned out to be a real uninitialized error in the code produced by the compiler - it wasn't bogus at all! The reason that it was exposed at -O2 was that loop unrolling exposed the path where the ubound was used uninitialized. That said, it turns out that it was very, very unlikely to matter at run-time.

I suspect that Sebastien's bug might be very similar. I'll take a look.

Cheers

Paul

glen herrmannsfeldt

unread,
Nov 30, 2013, 9:12:00 PM11/30/13
to
Richard Maine <nos...@see.signature> wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

>> You might try:
>>
>> allocate(raw(nx,ny),stat=ier)
>> if (failed_allocate('table_to_cube_data','raw array',ier).or.ier.ne.0)
>> return

> That's a good example of the kind of thing I said I recommended against.
> It's a hack with no purpose other than to (possibly) avoid a spurious
> compiler warning from a particular compiler and it makes the code
> confusing.

I think I might do something like:

allocate(raw(nx,ny),stat=ier)
if(ier.ne.0) call failed_allocate('table_to_cube_data','raw array',ier)
if(ier.ne.0) return

This separates the check of ier and the display of any message
from the condition for not continuing on.

> Were it not in this thread, I'd look at that and wonder what in the heck
> failed_allocate was checking. It sure would not occur to me that
> failed_allocate would always return the same value as the redundant
> ier.ne.0 test.

In the OP code, not only isn't it obvious to the compiler that it won't
continue on when the allocate fails, but it is also not obvious to the
reader. I suppose an appropriate comment could fix that, but then again
someone else might change failed_allocate and not the comment.


-- glen

Richard Maine

unread,
Dec 1, 2013, 9:18:22 AM12/1/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:
> > glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
> >> You might try:
> >>
> >> allocate(raw(nx,ny),stat=ier)
> >> if (failed_allocate('table_to_cube_data','raw array',ier).or.ier.ne.0)
> >> return
>
> > That's a good example of the kind of thing I said I recommended against.
> > It's a hack with no purpose other than to (possibly) avoid a spurious
> > compiler warning from a particular compiler and it makes the code
> > confusing.
>
> I think I might do something like:
>
> allocate(raw(nx,ny),stat=ier)
> if(ier.ne.0) call failed_allocate('table_to_cube_data','raw array',ier)
> if(ier.ne.0) return
>
> This separates the check of ier and the display of any message
> from the condition for not continuing on.

Yes. That's much more like what I'd do. In fact, it is reasonably close
to what I do do in simillar circumstances. I have a lot of code that
looks something like

if (istat /= 0) then
call write_error_message('Some message', istat)
goto 8000
end if

where 8000 is my error return location in the subroutine. I do like to
keep to the style of having a single return point. It provides a handy
place for any needed cleanup before return. That happens to be almost
the only context in which I use statement labels (and I forget why it
ended up being 8000, but that's the number I always use).

Sebastien Bardeau

unread,
Dec 2, 2013, 12:30:20 PM12/2/13
to
On 11/30/2013 03:31 PM, Richard Maine wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
>> You might try:
>>
>> allocate(raw(nx,ny),stat=ier)
>> if (failed_allocate('table_to_cube_data','raw array',ier).or.ier.ne.0)
> return
>
> That's a good example of the kind of thing I said I recommended against.
> It's a hack with no purpose other than to (possibly) avoid a spurious
> compiler warning from a particular compiler and it makes the code
> confusing.

I completely agree with this first answer by Richard (but not the
propositions in the next messages). The function factorizes the ier.ne.0
test, a message about the context to the user, and the "decoding" of the
ier value. I just don't want to unfactorize the ier.ne.0 test just to
hide this particular warning.

To my view this is exactly equivalent to:

subroutine mysub
integer(kind=4) :: a,b
call do_something(a)
b = a
end subroutine mysub

The "is-used-uninitialized" warning disappears just because 'a' is
passed to "do_something". From the compiler point-of-view, I /may/ have
initialized 'a', so it turns off the warning. There could be a
"maybe-used-uninitialized" warning, but there is not.

In my original example, I do the same: I pass 'ier' to a function, and
depending on how the function evaluates I /may/ return before using the
array. I see no difference...

... ok, there is one: the difference is that the compiler checks how I
use the array AND the allocation status. You will probably tell me this
becomes difficult to catch. I fully agree. But again, I won't modify my
code to something the compiler can catch more easily, so we are back to
Richard's answer above.

0 new messages