Skip to content

CWG2992 [basis.pre] Are labels names? #673

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

Open
Endilll opened this issue Feb 20, 2025 · 13 comments
Open

CWG2992 [basis.pre] Are labels names? #673

Endilll opened this issue Feb 20, 2025 · 13 comments

Comments

@Endilll
Copy link

Endilll commented Feb 20, 2025

[basic.pre]/3:

A name is an identifier ([lex.name]), conversion-function-id ([class.conv.fct]), operator-function-id ([over.oper]), or literal-operator-id ([over.literal]).

I believe the definition for name includes identifier within label ([stmt.label]):

label:
attribute-specifier-seqopt identifier :

However, [basic.pre]/5 states that:

Every name is introduced by a declaration <...>

Which is at odds with the fact that labels fit into the definition of name, but are statements, and not declarations.

P1787R6 "Declarations and where to find them" made major changes to the definition of name with the following intent:

Because labels interact with so little of the language, their identifiers are excluded from names and name lookup entirely.

It seems that the definition of name should be updated to make it clear that labels are not included.

Suggested resolution (2025-02-20):

Convert [basic.pre] paragraph 3 into a bulleted list, and apply the following changes:

A name is

@Endilll
Copy link
Author

Endilll commented Feb 20, 2025

I was pointed out to the fact that identifiers in attributes might be suffering from a similar wording defect. Given that they are explicitly exempted from undergoing name lookup, maybe they shouldn't be considered names either.

The more radical approach to fixing both issues would be to merge p3 and p5, saying that the grammar productions from p3 are names when they are a part of declarations listed in p5. This would eliminate all defects along the lines "it's an identifier, hence a name per p3, but it doesn't fit what p5 says."

@frederick-vs-ja
Copy link

I think it would be better to make p5 less restrictive.

  1. Every name is introduced by a declaration, which A declaration that introduces a name is a
    [...]

@jensmaurer
Copy link
Member

No. Labels are not names (because they are not subject to name lookup).

@cor3ntin
Copy link

@jensmaurer I still think @frederick-vs-ja 's suggestion would be an improvement here!

@Endilll
Copy link
Author

Endilll commented Feb 21, 2025

I think it would be better to make p5 less restrictive.

  1. Every name is introduced by a declaration, which A declaration that introduces a name is a
    [...]

Wouldn't this make label a name, because it satisfies p3?

@jensmaurer
Copy link
Member

CWG2992

@jensmaurer jensmaurer changed the title [basis.pre] Are labels names? CWG2992 [basis.pre] Are labels names? Feb 23, 2025
@cpplearner
Copy link

I think the conceptual model after P1787R6 is:

  1. An identifier is a name whether it is introduced by a declaration or not.
  2. In most cases, a name must be introduced by a declaration for it to be meaningfully used. In particular, name lookup usually requires a declaration to exist (http://eel.is/c++draft/basic.lookup.general#1.sentence-3).
  3. Certain other constructs also require a declaration to exist. For example, a declaration with a qualified-id requires a previous declaration.
  4. In other cases, a name does not need to have a declaration.

Now, uses of identifier labels do not interfere with declarations or name lookup. The fact that an identifier is a name does not matter at all.

This means [basic.pre]/3 is fine, but [basic.pre]/5 is problematic.

Every name is introduced by a declaration

Here is another example which shows that [basic.pre]/5 is problematic:

auto f(auto a) { g(a); }

g is a name (and it is subject to name lookup), but it is not introduced by a declaration and doesn't need to as long as f is not instantiated.

@jensmaurer
Copy link
Member

I disagree; I want the inverse approach. Labels and attributes are simply not names, and any statement to the contrary needs to be fixed.

For your g example, if g is never declared, then the program is IFNDR, because no valid specialization can be generated from the template. So, we do need a declaration of g somewhere.

@Endilll
Copy link
Author

Endilll commented Feb 24, 2025

I disagree; I want the inverse approach. Labels and attributes are simply not names, and any statement to the contrary needs to be fixed.

Then we need to turn https://eel.is/c++draft/dcl.attr#grammar-4.sentence-6 into a note, and say that identifiers within attribute-specifiers are not names, too.

@cpplearner
Copy link

I disagree; I want the inverse approach. Labels and attributes are simply not names, and any statement to the contrary needs to be fixed.

Why do you care if they are names or not? It doesn't matter at all.

For your g example, if g is never declared, then the program is IFNDR, because no valid specialization can be generated from the template. So, we do need a declaration of g somewhere.

Let's suppose that auto f(auto a) { g(a); } is exported from a module mod_a. A valid specialization can be generated by:

  1. Define a type struct A { friend void g(A) {} }, and export it from an unrelated module mod_b.
  2. Create a TU file_c.cpp that imports both mod_a and mod_b. Then
  3. Instantiate f<A> in file_c.cpp.

This doesn't cause the name g to be introduced when compiling mod_a.

@jensmaurer
Copy link
Member

I do care because I don't want "names" to exist that are not declared and/or not subject to name lookup. I find it a more consistent overall picture to have a "name" only where that implies a connection to name lookup.

Regarding g: Sure, but what's your point? I'm saying the program needs to have a declaration of g somewhere. You're saying that declaration might be in a different module. I agree, but that's still in the same program.

@cpplearner
Copy link

  1. Can a valid specialization be generated, if it is possible to generate one in a few steps, but these steps are not actually performed?
  2. Regardless of 1, could the presence of an unreachable declaration affect the validity of a template in an unrelated module?

@frederick-vs-ja
Copy link

  1. Can a valid specialization be generated, if it is possible to generate one in a few steps, but these steps are not actually performed?
  2. Regardless of 1, could the presence of an unreachable declaration affect the validity of a template in an unrelated module?

It seems to me that this example shows an unfortunate fact: theoretically, the validness of this function template can't be determined locally, and we can only consider well-formedness of the whole program in this case.

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

No branches or pull requests

5 participants