cplusplus / cplusplus/draft

The definition of "reference-compatible" is not accurate

Open
#5,239 2 comments 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

“cv1 T1” is reference-compatible with “cv2 T2” if a prvalue of type “pointer to cv2 T2” can be converted to the type “pointer to cv1 T1” via a standard conversion sequence ([conv]).

Does "can be converted to ... via a standard conversion sequence" comprise the case: the standard conversion sequence does exist, however, due to some other requirement, the standard conversion so necessitates is ill-formed? Specifically, if we assume the definition of reference-compatible means that: if the standard conversion sequence is ill-formed, then “pointer to cv2 T2” cannot be converted to the type “pointer to cv1 T1”; consider this example

struct A{
   A() = default;
   A(A const&){}  // #2
};
struct B: private A{};
B b;
const A& rf = b; // #1

A is reference-related to B, thus each bullet that requires "T1 is not reference-related to T2" is skiped. With the above assumption, A is not reference-compatible with B, thus each bullet that requires “cv1 T1” is reference-compatible with “cv2 T2” is skiped. Eventually, the case falls into [dcl.init.ref] 5.4.2

Otherwise, the initializer expression is implicitly converted to a prvalue of type “T1”. The temporary materialization conversion is applied, considering the type of the prvalue to be “cv1 T1”, and the reference is bound to the result.

The implicit conversion is the call A::A(A const&) with the argument b, where the parameter binding to the argument is identical to the reference binding at #1. This will cause the recursive inspection of the relevant bullets. Obviously, it's not the intent, the reference binding at #1 should be terminated at [dcl.init.ref] p4. That is, A is reference-compatible with B even if the standard conversion sequence is ill-formed due to inaccessibility. Maybe, we can improve the definition to be that

“cv1 T1” is reference-compatible with “cv2 T2” if ignore the base class is inaccessible(if any), there exists a standard conversion sequence that can convert a prvalue of type “pointer to cv2 T2” to the type “pointer to cv1 T1”([conv]). In all cases where the reference-compatible relationship of two types is used to establish the validity of a reference binding and the standard conversion sequence would be ill-formed, a program that necessitates such a binding is ill-formed.

The former is used to admit that A and B are reference-compatible while the latter is used to negative the well-formed associated with the binding since the base class A is inaccessible.

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 the reference-compatible definition in [dcl.init.ref] alongside the standard conversion rules in [conv]. Work through the A/B example, especially the inaccessible base and recursive reference binding, then determine wording that preserves reference compatibility while making the binding itself ill-formed where required. Done means the definition and example no longer produce the unintended recursive path.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, 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.