C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Detection of whether a determined user-defined literal is declared

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Tue, 15 Aug 2023 20:45:33 -0400
On Tue, Aug 15, 2023 at 8:24 PM Brian Bi via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Observation: the proposed detection feature does not make sense without
> `userexpr`. Even if you can determine, at compile time, a `bool` that tells
> you whether `42_km` is a valid user-defined literal, the only way you could
> possibly make use of that information is to avoid instantiating a template
> that contains `42_km` because you know that it's not valid. But that
> template, having not been instantiated, still makes the program IFNDR under
> [temp.res.general]/6 <http://eel.is/c++draft/temp.res.general#6>, bullets
> 1 and 5.
>

I think your logic has a gap, but it leads to the correct conclusion.
http://eel.is/c++draft/temp.res.general#6.1 mentions "constexpr if" but
only in the context of when the "innermost enclosing template is not
instantiated." That doesn't *directly* make the following usage IFNDR:

    template<class T>
    void f() {
        if constexpr (is_42_km_valid()) { // suppose this returns false
            42_km;
        }
    }
    int main() { f<int>(); }

But this code is actually ill-formed (diagnostic required) anyway, if I'm
not mistaken, because `42_km` is not (and cannot possibly be, right?) a
dependent expression. The compiler *knows* during phase 1 whether it's
valid, and will hard-error if it's not. There is no way to "hide" a
non-dependent expression from the compiler; and there is no way to turn
`42_km` into a dependent expression, either.

I still fail to understand this proposal. I think either it makes no sense
at all, or else it's conflating the idea of compile-time string values with
the idea of identifiers/names — like, the proposer is imagining that
there's some way in C++ to ask questions like
    bool is_there_a_variable_in_scope_named(const char *identifier);
    int how_many_function_overloads_are_visible_named(const char
*identifier);
    int what_is_the_value_of_the_enumerator(const char *enumerator_name);
    bool is_there_a_UDL_in_scope_named(const char *suffix);
There simply isn't. The names you write in your C++ source code "vanish" at
compile time, and aren't accessible at runtime — nor even at
compile-time-evaluation time. This is a good thing, because it permits
refactoring: I can rename a variable from `x` to `y` consistently
throughout its scope, and know that the program's behavior won't be
affected.(*)

Jens asked for an example of how the proposed feature would be used. I
haven't seen a reply to that yet. (I saw a sort-of proposed *implementation*,
but nothing about why it should exist or what kind of code would benefit
*from* it.)

–Arthur
(*Okay, except for certain names that are magic to the core language, such
as `tuple_element`, `tuple_size`, `begin`, `end`, `return_void`, ...)

Received on 2023-08-16 00:45:47