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

[temp.point] Clarify ambiguous wording on point of instantiation #6375

Open
Eisenwave opened this issue Jul 14, 2023 · 1 comment
Open

[temp.point] Clarify ambiguous wording on point of instantiation #6375

Eisenwave opened this issue Jul 14, 2023 · 1 comment

Comments

@Eisenwave
Copy link
Contributor

Eisenwave commented Jul 14, 2023

Motivation

There is a wording issue which led me to this problem, where I have (mis?)interpreted the wording and (falsely?) assumed that the following code is ill-formed:

template <typename T>
void fun(T t) {
    // foo and bar are not declared yet, but this is okay,
    // because they can be found through ADL for a class type T
    foo(t);
    bar(t);
}

struct A {};

void foo(A);

// implicitly instantiate fun<A>(A), with the point of instantiation being after call_fun
void call_fun() {
    fun(A{});
}

/* implicit instantiation should be here:

template void fun<A>(A t) {
    foo(t); // OK, foo has been declared
    bar(t); // NOT OK, bar has not been declared yet
}
*/

void bar(A);

See also: https://stackoverflow.com/q/76687729/5740428

The Wording Issue

For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization.
Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.

- [temp.point]/1

The relevant part is follows the namespace scope declaration or definition. There are two possible interpretations:

  1. "follows the declaration or definition AT namespace scope"
  2. "follows the declaration or definition OF THE namespace scope"

If we interpret it as 1., then the above code should indeed be ill-formed, because the instantiation of fun<A> follows call_fun. However, all compilers happily accept this code, so implementations must be interpreting this as 2., where the point of instantiation of fun<A> follows the global scope itself.

I am not certain which reading is truly correct, and it should be clarified by rephrasing it as 1. or 2..

@Eisenwave
Copy link
Contributor Author

There's actually a second ambiguity that I'm unsure about. In:

[...] follows the namespace scope declaration or definition that refers to the specialization.

Are we to read this as:

  1. "follows the namespace scope declaration that refers to the specialization, or the definition that refers to the specialization", or as
  2. "follows the declaration or definition of the namespace scope that refers to the specialization".

I guess it doesn't make much sense for there to be a declaration or definition of a namespace scope, but the wording is still confusing.

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

1 participant