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

[conv.qual] Improvement and supply the omitted result #5358

Open
xmh0511 opened this issue Mar 23, 2022 · 3 comments
Open

[conv.qual] Improvement and supply the omitted result #5358

xmh0511 opened this issue Mar 23, 2022 · 3 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Mar 23, 2022

[conv.qual] p3 omitted to specify the result of the conversion, it might be

The pointer value ([basic.compound]) is unchanged by this conversion.

it implies that the result has the same pointer value as the original.

admit only two similar types can undergo qualification conversion

The current wording just says

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

According to the definition of qualification-combined type, it just concerns whether the corresponding Pi and CVi satisfy some conditions. For example: int ** and char**.

#4860 has excluded an identity conversion from qualification conversion. But two types that have a difference only in their top-level cv-qualifications are also considered to be different types. For example:
int const vs. int, char* const vs. char*, they only differ in their top-level cv-qualifiers.

So, based on that, the wording might be changed to

A prvalue of type T1 can be converted to another type T2(ignoring cv-qualification) if T1 and T2 are similar and the qualification-combined type of T1 and T2 is T2.

duplicately add const

[conv.qual] p3.3 says

if the resulting cv3i is different from cv1i or cv2i or the resulting P3i is different from P1i or P2i, then const is added to every cv3k for 0< k < i

Consider a const has added in cv3k due to [conv.qual] p3.1. [conv.qual] p3.3 can result in a duplicate addition. For example:
T1 = int*** and T2 = int *const* const*, after applying [conv.qual] p3.1, T3 will be pointer to const pointer to const pointer to int where cv32 is different from cv12, however, cv31 does have a const. {const const } is not a valid set defined in [basic.type.qualifier] p6.

The change might be

if the resulting cv3i is different from cv1i or cv2i or the resulting P3i is different from P1i or P2i, then const is added to every cv3k for 0< k < i if cv3k haven't yet comprised a const

[conv.qual] p3 should apply to a pointer, a pointer to member types

Because the bullets in p3 refer to the component Pi that is defined as “pointer to”, “pointer to member of class Ci of type”, “array of Ni”, “array of unknown bound of”. So, the precondition for this definition should be n ≥ 1

The initial sentence might be changed to

The qualification-combined type of two types T1 and T2 is the type T3 similar to T1 whose qualification-decomposition(where n ≥ 1 ) is such that:

As a similar reason to the above, the definition of similar might be changed to

Two types T1 and T2 are similar if they have qualification-decompositions with the same n such that either there is no Pi component, or the corresponding Pi components are either the same or one is “array of Ni” and the other is “array of unknown bound of”, and the types denoted by U are the same.

@jensmaurer
Copy link
Member

  • A prvalue of built-in type is never cv-qualified.
  • Adding const twice is a harmless no-op.
  • n == 0 is valid and means no "pointer to" level at all. I think the rules work properly in that case.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 23, 2022

A prvalue of built-in type is never cv-qualified.

Yes, but it cannot clarify that we use the wording such as one type T1 can be converted to T2 with a qualification conversion, see [expr.const.cast] p7, maybe, there are also other places in the standard that use a similar utterance.

Adding const twice is a harmless no-op.

However, we say the symbol cvi is a set of cv-qualifiers ([basic.type.qualifier]) in [conv.qual] p1. [basic.type.qualifier] p6 lists the valid set

one of {const}, {volatile}, {const, volatile}, or the empty set.

There is no {const, const}.

n == 0 is valid and means no "pointer to" level at all. I think the rules work properly in that case.

when n is 0, there is no Pi component at all. In this situation, how could we say that each Pi how and how. Furthermore, in p3, we said that

where cvij and Pij are the components of the qualification-decomposition of Tj.

It has implied that the type to which the rule applied whose qualification-decomposition should at least comprise one "pointer to" component. Because we didn't say Pi can be empty.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Mar 23, 2022

Another issue is that [expr.const.cast] p7 does not coordinate well with [conv.qual] p3. Consider this example

static_cast<int const>(0);  // cast away constness? 

In this case, T1 is int while T2 is int const. As per [conv.qual] p3, the qualification-combined type of T1 and T2 is int. Obviously, the qualification-combined type of T1 and T2 is not T2. Thus, there is no qualification conversion from T1 to T2, hence the conversion violates "shall not cast away constness" principle? Even if we would fix [expr.const.cast] p7 with the wording

there is no qualification conversion that converts a prvalue of T1 to type T2

this issue remains existence becauseT2 is the interference in this case. My suggestion is the last sentence of [conv.qual] p3 might be changed to

if the qualification-combined type of T1 and T2 is cv3 T3 and T3 is the same as T2(ignoring cv-qualification).

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

2 participants