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

Scope in BLOCK - END BLOCK

268 views
Skip to first unread message

john.coll...@gmail.com

unread,
Feb 13, 2018, 7:25:39 AM2/13/18
to
In the following code, the variables i and j are undeclared and implicitly typed in the body of the subroutine. i and j are also undeclared in the BLOCK construct where both are assigned. Under gfortran, j, which is referenced before the BLOCK construct, is imported into and exported out of the BLOCK. i is referenced outside the block only after the BLOCK construct. It is not exported from the block and the variable inside the block is independent of that outside. The implication is that a BLOCK-END BLOCK construct divides the environment in which it is written into 3 scopes not 2. It matters whether a variable is referenced before or after the BLOCK construct.

Is this the intended behaviour? What happens with other compilers?

I realise that this situation will be rare. You need a computational death-wish if you rely on implicit typing in situations like this. However, if you are working on compilers or program analysis tools you need to know whether to scan the entire environment around a BLOCK construct to determine which objects are in scope, or just up to the start of the BLOCK.

Best wishes,

John

SUBROUTINE t_variable_export

WRITE(*,'(//,"Test of export of a new implicitly declared variable")')
j = 1
BLOCK
i = 42
j = 42
WRITE(*,'("i inside BLOCK: ",I2)')i
WRITE(*,'("j inside BLOCK: ",I2)')j
END BLOCK
WRITE(*,'("i after BLOCK: ",I2)')i
WRITE(*,'("j after BLOCK: ",I2)')j
WRITE(*,'("End of test of export of a new variable")')

END SUBROUTINE t_variable_export ! ********************************************

gfortran result:

Test of export of a new implicitly declared variable
i inside BLOCK: 42
j inside BLOCK: 42
i after BLOCK: 0
j after BLOCK: 42
End of test of export of a new variable

FortranFan

unread,
Feb 13, 2018, 9:26:31 AM2/13/18
to
On Tuesday, February 13, 2018 at 7:25:39 AM UTC-5, john.coll...@gmail.com wrote:

@John,

> ..
>
> Is this the intended behaviour?

Per my simple-minded read of the standard, yes I surmise as much.

In 8.1.4 BLOCK Construct, the standard states, "specifi cations in a BLOCK construct declare construct entities whose scope is that of the BLOCK construct" and Note 8.5, "Actions on a variable local to a BLOCK construct do not affect any variable of the same name outside the construct."

> What happens with other compilers?

Intel Fortran compiler 18.0 update 1 (latest version) shows same behavior:

C:\Temp>type p.f90
SUBROUTINE t_variable_export

WRITE(*,'(//,"Test of export of a new implicitly declared variable")')
j = 1
BLOCK
i = 42
j = 42
WRITE(*,'("i inside BLOCK: ",I2)')i
WRITE(*,'("j inside BLOCK: ",I2)')j
END BLOCK
WRITE(*,'("i after BLOCK: ",I2)')i
WRITE(*,'("j after BLOCK: ",I2)')j
WRITE(*,'("End of test of export of a new variable")')

END SUBROUTINE t_variable_export ! ********************************************
call t_variable_export()
end

C:\Temp>ifort p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R
) 64, Version 18.0.1.156 Build 20171018
Copyright (C) 1985-2017 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.12.25835.0
Copyright (C) Microsoft Corporation. All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe


Test of export of a new implicitly declared variable
i inside BLOCK: 42
j inside BLOCK: 42
i after BLOCK: 0
j after BLOCK: 42
End of test of export of a new variable

> .. if you are working on compilers or program analysis tools you need to know
> whether to scan the entire environment around a BLOCK construct to determine
> which objects are in scope, or just up to the start of the BLOCK.

Can not a program analysis tool do what the 'mental compiler' of a Fortranner might do which is to view the code snippet you show in the original post like so?

SUBROUTINE t_variable_export

WRITE(*,'(//,"Test of export of a new implicitly declared variable")')
j = 1
call SUB_BLOCK( j )
WRITE(*,'("i after call SUB_BLOCK: ",I2)')i
WRITE(*,'("j after call SUB_BLOCK: ",I2)')j
WRITE(*,'("End of test of export of a new variable")')

END SUBROUTINE t_variable_export ! ********************************************

SUBROUTINE SUB_BLOCK(j)

i = 42
j = 42
WRITE(*,'("i inside SUB_BLOCK: ",I2)')i
WRITE(*,'("j inside SUB_BLOCK: ",I2)')j

END SUBROUTINE SUB_BLOCK

Rudi Gaelzer

unread,
Feb 13, 2018, 9:48:22 AM2/13/18
to
On Tuesday, February 13, 2018 at 10:25:39 AM UTC-2, john.coll...@gmail.com wrote:
> gfortran result:
>
> Test of export of a new implicitly declared variable
> i inside BLOCK: 42
> j inside BLOCK: 42
> i after BLOCK: 0
> j after BLOCK: 42
> End of test of export of a new variable

Got exactly the same outcome compiling with Intel Fortran V. 18.
I guess this is against the spirit of block scope and the standard. I don't have the official document, only the J3/10-007r1 revision, which states in sec. 8.1.4 BLOCK construct, note 8.5:
"Actions on a variable local to a BLOCK construct do not affect any variable of the same name outside the construct."

Of course, the workaround is to enforce explicit typing with "implicit none". In this case, I strongly second the suggestions given in the document Steve Lionel posted (see thread https://groups.google.com/forum/#!topic/comp.lang.fortran/Upi8YuNRNeg) to consider implicit none as the standard option.

john.coll...@gmail.com

unread,
Feb 13, 2018, 10:15:51 AM2/13/18
to
You wrote:
On Tuesday, 13 February 2018 14:26:31 UTC, FortranFan wrote:
> On Tuesday, February 13, 2018 at 7:25:39 AM UTC-5, john.coll...@gmail.com wrote:
>
> @John,
>
> > ..
> >
> > Is this the intended behaviour?
>
> Per my simple-minded read of the standard, yes I surmise as much.
>
> In 8.1.4 BLOCK Construct, the standard states, "specifi cations in a BLOCK construct declare construct entities whose scope is that of the BLOCK construct" and Note 8.5, "Actions on a variable local to a BLOCK construct do not affect any variable of the same name outside the construct."
>

In the original code, both i and j are present in the environment of the BLOCK. The only difference is that j is referenced before the BLOCK and i is referenced after it. As far as I can see, the standard says nothing about the order of the statements in the code. j is imported and exported. A new variable is created for i which is local to the block. My question is why j is inherited but i is local.

You ask:
Can not a program analysis tool do what the 'mental compiler' of a Fortranner might do which is to view the code snippet you show in the original post like so?

SUBROUTINE t_variable_export

WRITE(*,'(//,"Test of export of a new implicitly declared variable")')
j = 1
call SUB_BLOCK( j )
WRITE(*,'("i after call SUB_BLOCK: ",I2)')i
WRITE(*,'("j after call SUB_BLOCK: ",I2)')j
WRITE(*,'("End of test of export of a new variable")')


If you move the block into an internal subroutine and do not add a declaration for i in the internal subroutine, i is inherited, not local. If you were to add a declaration for i, then why not for j which would then also become local? If you make SUB_BLOCK an external routine, you then have to get all of the other inherited variables (In this example only j) into it.

Best wishes,

John

Steve Lionel

unread,
Feb 13, 2018, 1:45:05 PM2/13/18
to
On 2/13/2018 4:25 AM, john.coll...@gmail.com wrote:
> In the following code, the variables i and j are undeclared and implicitly typed in the body of the subroutine. i and j are also undeclared in the BLOCK construct where both are assigned. Under gfortran, j, which is referenced before the BLOCK construct, is imported into and exported out of the BLOCK. i is referenced outside the block only after the BLOCK construct. It is not exported from the block and the variable inside the block is independent of that outside. The implication is that a BLOCK-END BLOCK construct divides the environment in which it is written into 3 scopes not 2. It matters whether a variable is referenced before or after the BLOCK construct.
>
> Is this the intended behaviour? What happens with other compilers?

No, it is not the intended behavior. Note 5.39 (though not normative),
covers this exact situation:
**
Implicit typing is not affected by BLOCK constructs. For example, in

SUBROUTINE S(N)
...
IF (N>0) THEN
BLOCK
NSQP = CEILING(SQRT(DBLE(N)))
END BLOCK
END IF
...
IF (N>0) THEN
BLOCK
PRINT *,NSQP
END BLOCK
END IF
END SUBROUTINE

even if the only two appearances of NSQP are within the BLOCK
constructs, the scope of NSQP is the whole subroutine S.
**

The normative text is 5.4.14p4:

"Any data entity that is not explicitly declared by a type declaration
statement, is not an intrinsic function, is not a component, and is not
accessed by use or host association is declared implicitly to be of the
type (and type parameters) mapped from the first letter of its name,
provided the mapping is not null. The mapping for the first letter of
the data entity shall either have been established by a prior IMPLICIT
statement or be the default mapping for the letter. The mapping may be
to a derived type that is inaccessible in the local scope if the derived
type is accessible in the host scoping unit. The data entity is treated
as if it were declared in an explicit type declaration in the outermost
inclusive scope in which it appears."

It is the last sentence that is the key. "inclusive scope" is:

"nonblock scoping unit plus every block scoping unit whose host is that
scoping unit or that is nested within such a block scoping unit
NOTE 1.5
That is, inclusive scope is the scope as if BLOCK constructs were not
scoping units."

It looks as if (at least) two compilers have a bug here. I'll report
this to Intel. (I haven't yet figured out how to use Bugzilla to report
to gfortran.)

Not directly related to this question, I'll add a reference to
interpretation F08/0074 (J3 paper 12-151r2), related to implicit typing
in a BLOCK construct.
--
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

steve kargl

unread,
Feb 13, 2018, 1:58:53 PM2/13/18
to
Steve Lionel wrote:

> On 2/13/2018 4:25 AM, john.coll...@gmail.com wrote:
>> In the following code, the variables i and j are undeclared and implicitly typed in the body of the subroutine. i and j are also undeclared in the BLOCK construct where both are assigned. Under gfortran, j, which is referenced before the BLOCK construct, is imported into and exported out of the BLOCK. i is referenced outside the block only after the BLOCK construct. It is not exported from the block and the variable inside the block is independent of that outside. The implication is that a BLOCK-END BLOCK construct divides the environment in which it is written into 3 scopes not 2. It matters whether a variable is referenced before or after the BLOCK construct.
>>
>> Is this the intended behaviour? What happens with other compilers?
>
> No, it is not the intended behavior. Note 5.39 (though not normative),

Which document are you looking at? N2137 does not contain a Note 5.39.

--
steve



Steve Lionel

unread,
Feb 13, 2018, 2:13:25 PM2/13/18
to
On 2/13/2018 10:58 AM, steve kargl wrote:
> Which document are you looking at? N2137 does not contain a Note 5.39.

10-007r1 (F2008). If you want N2137, see Note 8.40.

steve kargl

unread,
Feb 13, 2018, 2:25:11 PM2/13/18
to
Steve Lionel wrote:

> On 2/13/2018 10:58 AM, steve kargl wrote:
>> Which document are you looking at? N2137 does not contain a Note 5.39.
>
> 10-007r1 (F2008). If you want N2137, see Note 8.40.
>

Thanks. I'll see about getting a bug report filed for gfortran.

--
steve

FortranFan

unread,
Feb 13, 2018, 2:51:30 PM2/13/18
to
On Tuesday, February 13, 2018 at 1:45:05 PM UTC-5, Steve Lionel wrote:

> .. The data entity is treated
> as if it were declared in an explicit type declaration in the outermost
> inclusive scope in which it appears."
>
> It is the last sentence that is the key. "inclusive scope" is:
>
> "nonblock scoping unit plus every block scoping unit whose host is that
> scoping unit or that is nested within such a block scoping unit
> NOTE 1.5
> That is, inclusive scope is the scope as if BLOCK constructs were not
> scoping units."
>

Hmm.. I had wrongly read the inclusive scope reference in section 5.5 to mean the scope for the IMPLICIT statement, not as if a data entity were "declared in an explicit type declaration in the outermost inclusive scope in which it appears"


> It looks as if (at least) two compilers have a bug here. I'll report
> this to Intel. (I haven't yet figured out how to use Bugzilla to report
> to gfortran.)
>

No doubt it's always shame on me when I'm fooled by the standard. But when a couple of implementations get it wrong, the users will only find it amusing for so long!

So yes, it'll be nice if the section on BLOCK construct (e.g., 8.1.4 in 10-007r1 F2008) itself referred back to the section on IMPLICIT typing, similar to link to the section (e.g., 16.4 in F2008) on Statement and Construct entities.

Steve Lionel

unread,
Feb 13, 2018, 5:43:33 PM2/13/18
to
On 2/13/2018 11:51 AM, FortranFan wrote:
> No doubt it's always shame on me when I'm fooled by the standard. But when a couple of implementations get it wrong, the users will only find it amusing for so long!
>
> So yes, it'll be nice if the section on BLOCK construct (e.g., 8.1.4 in 10-007r1 F2008) itself referred back to the section on IMPLICIT typing, similar to link to the section (e.g., 16.4 in F2008) on Statement and Construct entities.

More interesting is that the critical sentence under IMPLICIT is no
longer there in the F2018 draft, and I can't find where it might have
moved to. I have asked the Editor for his comments.

steve kargl

unread,
Feb 13, 2018, 6:31:00 PM2/13/18
to
Steve Lionel wrote:

> On 2/13/2018 11:51 AM, FortranFan wrote:
>> No doubt it's always shame on me when I'm fooled by the standard. But when a couple of implementations get it wrong, the users will only find it amusing for so long!
>>
>> So yes, it'll be nice if the section on BLOCK construct (e.g., 8.1.4 in 10-007r1 F2008) itself referred back to the section on IMPLICIT typing, similar to link to the section (e.g., 16.4 in F2008) on Statement and Construct entities.
>
> More interesting is that the critical sentence under IMPLICIT is no
> longer there in the F2018 draft, and I can't find where it might have
> moved to. I have asked the Editor for his comments.
>

I think you're looking for lines 6-9 on page 121 of N2137.
This then gives NOTE 8.40.

--
steve

Steve Lionel

unread,
Feb 13, 2018, 7:13:32 PM2/13/18
to
On 2/13/2018 3:30 PM, steve kargl wrote:

>> More interesting is that the critical sentence under IMPLICIT is no
>> longer there in the F2018 draft, and I can't find where it might have
>> moved to. I have asked the Editor for his comments.
>>
>
> I think you're looking for lines 6-9 on page 121 of N2137.
> This then gives NOTE 8.40.

Malcolm pointed me to 19.1p2 which says, simply:

The scope of ...
- a local identifier is an inclusive scope

(The same words are in F2008.)

His paper on this said:

"It is unclear why we are attempting to duplicate the scoping rules at
this point in the standard. The scoping rules for local and construct
entities are described elsewhere (clause 19), so attempting to describe
them again here will at best be redundant, and is more likely to be
contradictory.

Furthermore, to say that it is treated as if it were declared "by an
explicit type declaration" adds nothing; we've already said what the
type and type parameters are."

This doesn't change the fact that both ifort and gfortran got this wrong.

FortranFan

unread,
Feb 13, 2018, 7:23:51 PM2/13/18
to
On Tuesday, February 13, 2018 at 5:43:33 PM UTC-5, Steve Lionel wrote:

> ..
> More interesting is that the critical sentence under IMPLICIT is no
> longer there in the F2018 draft, and I can't find where it might have
> moved to. I have asked the Editor for his comments.
> ..

Thanks much for your follow-up. The operative phrase "outermost inclusive scope" can't be located anywhere else in N2146 document toward Fortran 2018 standard either. And yes, without the critical sentence, "The data entity is treated as if it were declared in an explicit type declaration in the outermost inclusive scope in which it appears" in N2146 (or a suitable replacement for it), it will come across as a deviation from 10-007r1 toward Fortran 2008, at least to the laity.

Steve Lionel

unread,
Feb 13, 2018, 7:27:29 PM2/13/18
to
On 2/13/2018 3:30 PM, steve kargl wrote:
> I think you're looking for lines 6-9 on page 121 of N2137.

Those words were deleted between N2137 and N2146 - see my earlier post.
N2146 is the DIS, which is what you should be looking at now.

FortranFan

unread,
Feb 13, 2018, 8:07:33 PM2/13/18
to
On Tuesday, February 13, 2018 at 7:13:32 PM UTC-5, Steve Lionel wrote:

> ..
> Malcolm pointed me to 19.1p2 which says, simply:
>
> The scope of ...
> - a local identifier is an inclusive scope
>
> ..
> This doesn't change the fact that both ifort and gfortran got this wrong.
> ..

Should not the concept of "local identifier" (and global) be introduced earlier in the standard document, perhaps in section 5 on data concepts? What about local (and global) identifier being listed under 3 Terms and Definitions - anyone this that will be a good idea?

Isn't leaving an important point, that is at the very foundation of the issue in the original post of this thread, to a concept introduced all the way back in section 19 leading to a possibility implementations and readers will overlook it?

john.coll...@gmail.com

unread,
Feb 14, 2018, 7:07:06 AM2/14/18
to
Thank you, Steve Lionel, Steve Kargl and FortranFan.

The joy of this is that we now have to provide support for both the "standard" and the "gfortran/ifort" interpretations. I think a warning when the first implicitly typed occurrence of a variable is in a block should do it. This is going to be rare anyway.

Best wishes,

John

Mohammad

unread,
Feb 14, 2018, 7:49:58 AM2/14/18
to
I read from

https://www.ibm.com/support/knowledgecenter/SSGH4D_15.1.0/com.ibm.xlf151.aix.doc/language_ref/block.html

The Block construct:


"""
PROGRAM MyProgram
INTEGER :: i
i = 100

BLOCK
INTEGER :: i
i = 1
! Before the BLOCK construct is exited, local allocatables are
! deallocated, and local finalizable objects are finalized.
GOTO 10
i = i + 1
END BLOCK

10 PRINT *, i
END PROGRAM MyProgram
"""

Does it means we have goto again Fortran 2008?!!!

Arjen Markus

unread,
Feb 14, 2018, 8:40:10 AM2/14/18
to
What makes you think that GOTO was gone? What makes you think that GOTO is necessary? In this example it is used for reasons I cannot quite comprehend but the page you refer to has a very different example.

BLOCK has nothing to do with GOTO - except perhaps that you cannot jump into a BLOCK (in contrast to jumping out).

Regards,

Arjen

Mohammad

unread,
Feb 14, 2018, 9:56:59 AM2/14/18
to
Goto was used to jump outside the block! this is an unconditional goto, it is an example.
For may years we told we should avoid goto to have a more readable code and better logic!

Wolfgang Kilian

unread,
Feb 14, 2018, 10:18:50 AM2/14/18
to
Don't think in terms of dogma. In the trivial example above, EXIT might
be preferable. However, something like this

subroutine ...

block
...
if (error_condition) go to 10
...
if (another_error) go to 20
...
end block
return

10 continue
<error handler>
return

20 continue
<error handler 2>
return

end subroutine ...

could be an actual long version of the example, and perfectly legitimate.

You are looking at a TRY-CATCH exeption handler construct here. Such a
control structure does not exist in Fortran. There are different ways
to emulate this logic in Fortran, one of them is shown above. All
versions are equally good or bad. The explicit GOTO labels at least
stand out when reading the code.

The Fortran 20xx survey results indicate that exception handling might
be considered for the next revision.

In any case, it is good to know that GOTO and EXIT both do all necessary
cleanup. Precisely what is needed for an exception handler.

-- Wolfgang


--
E-mail: firstnameini...@domain.de
Domain: yahoo

steve kargl

unread,
Feb 14, 2018, 1:37:36 PM2/14/18
to
I have opened a bug report for gfortran.


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84386

--
steve

Mohammad

unread,
Feb 14, 2018, 11:00:45 PM2/14/18
to
@Steve
Thank you for sharing!

Mohammad

unread,
Feb 14, 2018, 11:02:49 PM2/14/18
to
> Domain: yahoo

@Wolfgang
I think with respect the background of GOTO in classical Fortran, it is much better to implement the exception handler in a better way not using GOTO
I know there is not such feature in Fortran right now!

robin....@gmail.com

unread,
Feb 18, 2018, 8:50:48 AM2/18/18
to
On Wednesday, February 14, 2018 at 5:45:05 AM UTC+11, Steve Lionel wrote:
Reminds me of Stubby Kaye:
"There's phrases there that no-one understands ..."

(Does life imitate art?)
0 new messages