Skip to content

idea: postfix pointer-dereference operator #10011

Closed

Description

@1fish2

This is something of a wild idea: Use a postfix operator to dereference a pointer (as in Pascal) for fewer mistakes:

(*rect).area() becomes rect~.area()

That reads left-to-right with nary a precedence mistake.

Although Rust’s auto-dereference feature and type checker will sometimes catch the mistaken *rect.area(), it's good to just fix the failure mode. (All security holes in the field got past the type checker and the unit tests.)

The disadvantages are (1) the changeover work, and (2) being different than C/C++. C defined it that way to reuse the expression parser to help fit the compiler on a 16-bit CPU.

David Piepgrass points out that if pointer dereference were a suffix operator, it would have to be changed from * to (e.g.) ~. Why? Because if foo* means "dereference foo" then it becomes ambiguous whether foo * - bar means (foo*)-bar "dereference foo and subtract bar" or foo*(-bar) "multiply foo by negated bar". Due to this ambiguity, it is difficult for a language to simultaneously have

  1. Operators that can be prefix or infix, and
  2. Operators that can be infix or suffix.

To avoid the ambiguity, one can introduce an operator like ~ that is prefix or suffix but never infix.

Activity

  1. Thiez commented on Oct 22, 2013

    @Thiez
    Contributor

    (All security holes in the field got past the type checker and the unit tests.)

    I am interested, could you elaborate on this?

  2. 1fish2 commented on Oct 22, 2013

    @1fish2
    Author

    Rich Hickey points out in http://www.infoq.com/presentations/Simple-Made-Easy that all bugs in shipped software got past the type checker and the unit tests. Automatic array bounds checks and other run-time checks limit the damage of some additional problems.

    Security holes are bugs that are exploitable. They could come about due to memory safety problems, trusting externally-supplied data, numeric overflow, underlying OS and network flaws, etc.

    Something I learned in an IEEE Reliability Society talk is the path to reliability is eliminating as many failure modes as possible. Their example was automotive: Rather than diddle with the probability of A/C hoses rusting out, just use a material that doesn't corrode.

  3. Aatch commented on Nov 5, 2013

    @Aatch
    Contributor

    I'd like to see a Rust example where this is actually a possibility. Between autoderef and the type checker, I'm not sure if it's possible to introduce an actual bug. I mean, sure, there probably is some case, but I can't think of one that is caused purely by operator precedence mistakes.

    If you do *foo.abc() you are dereferencing the result of caling the abc method. If that type is not a pointer, then you'll get an error. If it is a pointer, then it should either be safe to dereference, a raw pointer (and therefore in an unsafe block), or a compile time error. The same ideas apply to (*foo).abc() except that code would only make sense if foo was a raw pointer, making the dereference itself unsafe.

    I'm closing this as unproductive, with no obvious advantage beyond "don't have to worry about operator precedence in this one case where it probably doesn't matter anyway", I can't see this happening. If you can provide a compelling example, this issue can be re-opened.

  4. 1fish2 commented on Nov 5, 2013

    @1fish2
    Author

    Fair enough.

    [(*foo).abc() and (*foo).abc also work for unique, borrowed, and managed pointers, right?]

    I don't have a compelling example, and consistent use of autoderef avoids the problem. Maybe if state points to an FSM state and (*state).next(token) returns the next FSM state pointer given an input token, then *state.next(token) === *(state.next(token)) gets the next state (not state pointer)... The type checker will catch that. With type inference the error message might be downstream but hopefully it'll still be a clear enough message.

    "Closed" is fine. Sorry for the digression.

  5. huonw commented on Nov 5, 2013

    @huonw
    Contributor

    [(*foo).abc() and (*foo).abc also work for unique, borrowed, and managed pointers, right?]

    Yes

  6. added a commit that references this issue on Feb 26, 2023
    b528cc9
  7. added a commit that references this issue on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions