cplusplus / cplusplus/draft

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

Open
#6,375 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TeX
Stars
221
Forks
813
Avg merge
16h 4m
Merged PRs (30d)
36

Description

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..

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading [temp.point]/1 and the example in this issue, then compare the two possible readings against the behavior of the compilers mentioned. Resolve whether the wording means the declaration at namespace scope or the declaration of the namespace scope, and revise the standard wording so the intended interpretation is unambiguous.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.