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

[basic.scope.block] p1 The note should be as a normative rule #4841

Open
xmh0511 opened this issue Aug 26, 2021 · 11 comments
Open

[basic.scope.block] p1 The note should be as a normative rule #4841

xmh0511 opened this issue Aug 26, 2021 · 11 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Aug 26, 2021

Each

  • selection or iteration statement ([stmt.select], [stmt.iter]),
  • substatement of such a statement,
  • handler ([except.pre]), or
  • compound statement ([stmt.block]) that is not the compound-statement of a handler

introduces a block scope that includes that statement or handler.

[Note 1: A substatement that is also a block has only one scope. — end note]

Isn't that note should be phrased as a normative rule? My proposal is that

Each

  • [...]
  • substatement of such a statement that is not a compound-statement,
  • [...]
  • compound statement ([stmt.block]) that is not the compound-statement of a handler

introduces a block scope that includes that statement or handler.

[Note 1: A substatement that is also a block has only one scope. — end note].

if(true) {
}

The substatement is a compound-statement, hence the second bullet does not apply but the last bullet does, which means the substatement only introduced one block scope.

@jensmaurer
Copy link
Member

I disagree there is a need to clarify this normatively; I think the note is good enough for directing the reading here.

@opensdh, any thoughts on this?

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 26, 2021

If there is no normative rule, we could say the compound-statement of the selection statement can introduce two blocks, please note the wording Each, a compound-statement of the selection statement is both the substatement and the compound-statement itself, which satisfies the second bullet and the last bullet.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 26, 2021

To stress the opinion, please consider this example

if(int a = 1)
  if(int a = 0){}

The declaration of a in the second line will not violate [basic.scope.block] p2, since the substatement of the first selection statement is both a substatement itself and is a selection statement, hence according to the first and second bullet of [basic.scope.block] p1, it will introduce two block scopes.

@opensdh
Copy link
Contributor

opensdh commented Aug 26, 2021

I agree with @jensmaurer. A statement that matches two bullets doesn't produce two scopes; it just produces one scope for two different reasons. (It might be more reasonable to read it as two scopes if "and" separated the bullets, but even then there's only one object to have this property.) It's true that the if(…) if(…) example is another way that a statement can deserve a scope in two different ways; we could extend the note to cover that too if that would help.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 26, 2021

@opensdh

It's true that the if(…) if(…) example is another way that a statement can deserve a scope in two different ways;

If the second if(...) only introduces one scope, then the declaration in it would violate [basic.scope.block#2]. Since the parent scope of the the target scope of the second declaration of a is the scope introduced by the first if, which contains another declaration of a, they are potential conflict. However, the example is accepted by all compilers https://godbolt.org/z/rWac8j8vW

@jensmaurer
Copy link
Member

@opensdh: The concern is the treatment of these two examples:

void f()
{
  if (int a = 1)
    if (int a = 0) ;     // #1 OK

  if (int b = 1) {
    int b = 0;            // #2 error
  }
}

#1 combines the "selection statement" and "substatement" bullets of [basic.scope.block] p1 and is ok (according to gcc and clang). #2 combines the "substatement" and "compound-statement" bullets of [basic.scope.block] p1 and is ill-formed.

I can't reconcile the different treatment of #1 and #2 by the compilers with the normative wording we're looking at. To make that work, the model for #1 needs to be if (int x = 1) ... is rewritten to { int x = 1; if (x) ... }, but we lack normative words to say that.

@jensmaurer
Copy link
Member

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 27, 2021

@jensmaurer After the above fix. I think we could add "or, if not that" into the end of each item in [basic.scope.block] p1, which will make that "just produces one scope for two different reasons." more clear.

@xmh0511
Copy link
Contributor Author

xmh0511 commented May 6, 2022

For this issue. We might say

Each distinct statement of the following:

  • [...]

introduces a block scope that includes that statement or handler.

This might clarify this issue. Since the compound statement itself as the substatement of a selection statement is the same statement, it introduces only one scope.

@opensdh
Copy link
Contributor

opensdh commented May 6, 2022

I still don't see the need to do anything here: a list of "every Fibonacci number or cube less than 100" doesn't include 8 twice and 1 three times.

@xmh0511
Copy link
Contributor Author

xmh0511 commented May 7, 2022

"every Fibonacci number or cube less than 100" doesn't include 8 twice and 1 three times

Because, either Fibonacci number or cube, it has a clear mathematical definition and formulation from which each value arises. Back to natural language, consider this case

Each person in the group X

  • has an apple, or
  • has a banana

The group X gets one score.

Assume a person has an apple and a banana, the group should get two scores because the person satisfies two. It wouldn't happen that the group X could only get one score due to the person has dedicated one score due to his apple so the one score for the banana would be discarded.

IMO, the application of the bullet is equivalent to

for(auto i : list){  // list is we defined
   if(statement.has(i) == true){  
      statement.introduces_block++;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants