Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing "const" on pointed to data #5

Open
certik opened this issue Oct 16, 2019 · 17 comments
Open

Allowing "const" on pointed to data #5

certik opened this issue Oct 16, 2019 · 17 comments
Labels
Clause 8 Standard Clause 8: Attribute declarations and specifications Fortran 2023 Proposal targeting the next Fortran standard F2023 (previously called F202X)

Comments

@certik
Copy link
Member

certik commented Oct 16, 2019

Currently one can enforce "const" using intent(in) for the pointer itself, but not the data it points to. One request we got was to also allow enforcing "const" on the data itself.

@zjibben zjibben added the unsubmitted Has not been submitted to the committee yet label Oct 16, 2019
@zbeekman
Copy link

In what context? Are you referring to the actual arguments associated with procedure dummy arguments? The current semantics of intent(in) on pointers gives a lot of flexibility and I would be upset if it was simply extended to apply to the target as well as the pointer allocation/association status.

@certik
Copy link
Member Author

certik commented Oct 17, 2019

I am just relying a request that we got: my understanding of the request was some mechanism to (optionally) request also const on the pointed to data, not that intent(in) was simply extended to apply to the target as well.

The answer might still be no.

@cmacmackin
Copy link

I don't see very many cases where this would be useful. If you are using intent(in) then you can't change the destination of the pointer and all that is available is to enquire about it's association status or to use it as a target. The latter could be achieved while keeping the value itself constant by changing the variable attributes to target, intent(in). The remaining case of checking association status does not seem particularly useful to me. I suppose it could allow the pointer to be used in a way sort of like an optional value, with the procedure using its value if it is associated and otherwise using a default. However, that would certainly not be worth losing the flexibility the current behaviour gives. Maybe it would be worth adding some additional intent (e.g., fixed or const), which wouldn't do any harm, but I can't see a huge amount of benefit either.

@zjibben
Copy link
Member

zjibben commented Oct 21, 2019

The way I understood the request was that it was loosely related to #16. As it stands, there's no way to pass a read-only pointer or target into a function--the data is always mutable when it gets one of those attributes. But you might want to share a data pointer or target without sharing write access. I don't think the suggestion was to modify current behavior of pointer or target, just to offer some kind of mechanism to safeguard against unwanted modification. The protected attribute referenced in #16 gives read-only access to non-pointer data, but pointer data is still mutable.

@cmacmackin
Copy link

cmacmackin commented Oct 21, 2019 via email

@zjibben zjibben added Fortran 2023 Proposal targeting the next Fortran standard F2023 (previously called F202X) and removed unsubmitted Has not been submitted to the committee yet labels Feb 28, 2020
@certik
Copy link
Member Author

certik commented Feb 28, 2020

This was submitted as https://j3-fortran.org/doc/year/18/18-144r1.txt, and also there is a new proposal on the way.

@certik
Copy link
Member Author

certik commented Mar 2, 2020

@klausler had a nice draft of how this can work including syntax. Peter, do you recommend to base the new paper for the next meeting off of your draft, or start from 18-144r1?

@tclune
Copy link
Member

tclune commented Mar 2, 2020

Tuning in late. For those that don't want to read the paper cited above, I want to point out that the initial part of the thread was on the wrong track. The idea is not to change the existing implications of INTENT for dummy pointer arguments, but rather to allow additional specification for the TARGET. The usual case would presumably be to prevent a subroutine from altering the values of the target.

This could be either by something like

real, pointer, INTENT(IN), TINTENT(IN) :: x

or

real, pointer, INTENT(IN,TARGETIN) :: x

I'm increasingly in favor of an entirely different approach which would be more general. Namely, a feature that would allow declaring a pointer for which one cannot modify the target through that pointer. This is roughly analogous to a const pointer in C. And it could be used beyond dummy arguments.

@certik
Copy link
Member Author

certik commented Mar 2, 2020

@tclune thanks for the clarification. Yes, I think the feature that people asked me to advocate for is something like real, pointer, INTENT(IN,TARGETIN) :: x, as you mentioned. (Update: although as Zach mentions below, it's possible the more general feature is in fact what they asked us for.)

Why don't you open a new issue for the more general "const pointer" approach? Let's discuss it there.

@zjibben
Copy link
Member

zjibben commented Mar 2, 2020

@tclune this more general approach would be great. I know multiple teams at LANL are very interested in such a feature. In fact it's possible that's what was intended by this issue, given that it derived from conversations with people at LANL.

@FortranFan
Copy link
Member

FortranFan commented Mar 2, 2020

@certik wrote:

@tclune , ..
Why don't you open a new issue for the more general "const pointer" approach? Let's discuss it there.

Fortran has named constants which it attributes as PARAMETERs and which can go into the READONLY area of a program memory and be absolutely immutable from compile-time onward. But then Fortran also has PROTECTED attribute for which a module scope comes into play in terms of being definable/modifiable. With pointers, the scope of the target cannot be limited to a particular module and it can very well be global.

So for a more general feature, perhaps Fortran can consider the notion of, say:

  <some type>, POINTER, CONST_TARGET :: foo

that can apply to dummy arguments as well as variables? And the semantics can be the same (or very similar) to "constant pointers" in C?

And for generality, it will be convenient if named constants can take the TARGET attribute with the restriction only constant pointers can point to them. There have been discussions on comp.lang.fortran where Fortran practitioners have expressed a strong interent in being able to point constant pointers to constant targets such as named constants.

@tclune
Copy link
Member

tclune commented Mar 2, 2020

@tclune thanks for the clarification. Yes, I think the feature that people asked me to advocate for is something like real, pointer, INTENT(IN,TARGETIN) :: x, as you mentioned. (Update: although as Zach mentions below, it's possible the more general feature is in fact what they asked us for.)

Why don't you open a new issue for the more general "const pointer" approach? Let's discuss it there.

I'm not so certain a new issue is warranted. The title of this issue seems quite appropriate. Indeed, a better argument could be made to open a new issue that restricts the discussion to just dummy pointers.

@certik
Copy link
Member Author

certik commented Mar 2, 2020

Thanks Peter. @tclune that's fine, we can discuss both proposals here.

@milancurcic milancurcic added the Clause 8 Standard Clause 8: Attribute declarations and specifications label Oct 27, 2021
@aradi
Copy link
Contributor

aradi commented Nov 25, 2021

Is there any progress here? Maybe, the following example may serve as a further argument, why the target-constantness should be considered by the language in some form. Currently, you can easily change intent(in) dummy arguments within a subroutine:

module test
  implicit none

contains

  subroutine sub1(val)
    integer, target, intent(in) :: val
    call sub2(val)
  end subroutine sub1

  subroutine sub2(ptr)
    integer, pointer, intent(in) :: ptr
    ptr = 42
  end subroutine sub2
end module test

program testprog
  use test
  implicit none

  integer :: val = 0
  print *, "VAL BEFORE:", val  !<-- prints "0"
  call sub1(val)
  print *, "VAL AFTER :", val   !<-- prints "42"

end program testprog

I am kind of inclined to think, that is is more a bug than a feature of the language.

@sblionel
Copy link
Member

At the October 2021 meeting, J3 voted to ask WG5 to drop "pointer intent" from 202X, with the hope of getting it in for 202Y. There has been lots of discussion, but time ran out on coming up with a solid proposal. I do think that most members are aligned on what is ultimately wanted. See https://j3-fortran.org/doc/year/21/21-195.txt

@aradi
Copy link
Contributor

aradi commented Nov 26, 2021

@sblionel Thanks for the feedback. It is promising, that at least there seems to be consensus, that this should be considered in some form. 😄

@klausler
Copy link

klausler commented May 18, 2022

For maximum safety and for best alias analysis, I believe now that additional attributes should be available for both data pointers and for data targets.

At present, a data pointer can be associated with any compatibly-typed object on the same image with the TARGET attribute. I suggest that:

  1. There be a means to restrict an associated data pointer's pointed-to object from appearing in a definition context. Call this a read-only pointer here. This is basically what we've been discussing so far, but not limited to a dummy argument.
  2. There be a means to restrict a TARGET object so that only a read-only pointer may be associated with it. Call this a read-only TARGET.
  3. There be a means to further restrict a read-only pointer to be associated only with read-only targets. Call this a safe read-only pointer.

The distinction between an "unsafe" read-only pointer and a safe read-only pointer is that alias analysis must assume that the pointed-to object of an "unsafe" read-only pointer might be modified by way of a non-read-only pointer. But a safe read-only pointer's pointed-to object cannot be modified by way of a non-read-only pointer. It is nearly as "optimizable" as an INTENT(IN) dummy argument.

A read-only pointer (safe or not) would be allowed to be associated with non-local data in a PURE procedure, including the case of default pointer component initialization.

  real :: x, y, p, q, s
  target :: x
  target, readonly :: y
  pointer :: p
  pointer, readonly :: q
  pointer, readonly, safe :: s

  p => x ! ok
  p => y ! BAD
  p => q ! BAD
  p => s ! BAD
  q => x ! ok
  q => y ! ok
  q => p ! ok
  q => s | ok
  s => x ! BAD
  s => y ! ok
  s => p ! BAD
  s => q ! BAD
  x = 1. ! ok
  y = 1. ! ok
  p = 1. ! ok
  q = 1. ! BAD
  s = 1. ! BAD

In short, a "safe" read-only pointer is an alias only for objects that are read-only targets. An "unsafe" read-only pointer can be associated with any target.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Clause 8 Standard Clause 8: Attribute declarations and specifications Fortran 2023 Proposal targeting the next Fortran standard F2023 (previously called F202X)
Projects
None yet
Development

No branches or pull requests

10 participants