cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[conv.qual] p3 `is` vs. `can` in the definition #353

Open xmh0511 opened 1 year ago

xmh0511 commented 1 year ago

Full name of submitter (unless configured in github; will be published with the issue): Jim X

[conv.qual] p3 says:

The qualification-combined type of two types T1 and T2 is the type T3 similar to T1 whose qualification-decomposition is such that:

  • [...]

A prvalue of type T1 can be converted to type T2 if the qualification-combined type of T1 and T2 is T2.

Consider this case:

int main(){
    int* ptr = 0;  // T1: int*
    int const* ptr2 = ptr; // T2: int const*
}

According to the definition of qualification-combined type, T3 can be int const*, which is exactly the same as T2, and int const* const, which is merely similar to T2. Both are similar to T1. However, "is" implies that the qualification-combined type of T1 and T2 must be only T2. In this case, if we consider the qualification-combined type as int const* const, which totally obeys the definition, however, it is not T2.

Suggested Resolution

The qualification-combined type of T1 and T2 can have more than one possible types(specifically, only have two?), we may say

A prvalue of type T1 can be converted to type T2 if the qualification-combined type of T1 and T2 ~is~ can be T2.

jensmaurer commented 1 year ago

I think we want to retain the property that qualification-combined type is a unique type, and handle differences in top-level cv-qualification (which generally don't matter) elsewhere. I do appreciate that the definition of qualification-combined type doesn't define cv_0 of the combined type.

xmh0511 commented 1 year ago

we want to retain the property that qualification-combined type is a unique type ... (which generally don't matter) elsewhere

The defined type may matter when we define casts away constness([expr.const.cast] p7) if we only admit only one type.

int* ptr = 0;
static_cast<int const* const>(ptr);  // #1
static_cast<int const*>(ptr);  // #2

If we only admit a unique type, then either #1 or #2 will be considered as cast away constness.

frederick-vs-ja commented 1 year ago

Perhaps we can drop top-level cv-qualifiers of scalar types in explicit cast operators before further processing (currently, the top-level cv-qualifiers seem to be dropped after casting). If so, the target types of #1 and #2 are both int const*.