Skip to content

[SUGGESTION] eliminate operator precedence (and require parens) #622

Description

@nigeltao

Is 3 << 5 - 1 parsed as (3 << 5) - 1 or 3 << (5 - 1)? C++ and Go give different answers!

#include <iostream>

int main() {  // Prints 48, which is "3 << (5 - 1)".
  int x = 3 << 5 - 1;
  std::cout << x << std::endl;
  return 0;
}
package main

import "fmt"

func main() {  // Prints 95, which is "(3 << 5) - 1".
	x := 3 << 5 - 1
	fmt.Println(x)
}

Similarly, 6 & 2 == 2 is 6 & (2 == 2) in C++ but (6 & 2) == 2 in Go. These reduce to 6 & 1 for C++ and 2 == 2 for Go, which are obviously different (0 and true).

For reference: C++ Operator Precedence and Go Operator Precedence

Like any curly-bracket language, Go looks a lot like C++, but copy/pasting a Go snippet from stackoverflow.com into a C++ program might have subtly different semantics.


I acknowledge that the SUGGESTION template says:

Please do not suggest syntax changes. I accept there are hundreds of opinions and everyone will prefer something a little different.

However, it also says "Please limit suggestions to quantifiable improvements to C++ simplicity, safety, or toolability" and there is a safety angle here. Operator precedence ambiguity has been a source of bugs in parsers. For example, in a library that emphasizes safety: jbangert/nail#7

Simplifying (by eliminating the idea of and need for precedence) is also similar to simplifying C++'s const T* type syntax. In C++, is it (const T)* or const (T*)? In cppfront, * const T is unambiguous, reading left-to-right.


The concrete suggestion: mandate parentheses when combining multiple binary operators. The programmer has to explicitly write either (3 << 5) - 1 or 3 << (5 - 1). A bare 3 << 5 - 1 would be a compiler error.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions