C++ Logo

std-proposals

Advanced search

Re: [std-proposals] D3077R0 Proposal of static_cast shorthand: <T>(x) DRAFT 1

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sat, 30 Dec 2023 09:54:17 -0500
On Fri, Dec 29, 2023 at 4:30 PM Andrew Tomazos via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Please find attached a short 2-page proposal:
>
> D3077R0 Proposal of static_cast shorthand: <T>(x) DRAFT 1
> https://isocpp.org/files/papers/D3077R0.pdf
>

Well, replacing `static_cast<T>(x)` with `<T>(x)` is obviously not a good
idea. You shouldn't waste the Committee's time with that.
But if you want to get involved in that area, I think it would be
productive (although there'd be *vastly* more thinking involved) to look at
the existing functional-cast syntax and work on making it Do The Right
Thing more often.
C++ has many many cast syntaxes already (which is why we don't need one
more):

  reinterpret_cast<T>(x)
  const_cast<T>(x)
  dynamic_cast<T>(x)
  std::bit_cast<T>(x) [put into the library for some reason]
  static_cast<T>(x)
  T(x) and T() and T(x,y) [this is the most important one, because it's
the most commonly used and the *only* syntax that exists in most other
mainstream languages]
  T{x} and T{} and T{x,y}
  (T)x and (T){} and (T){x,y}

The `T(x)` syntax has at least two big pitfalls:
https://quuxplusone.github.io/blog/2020/01/22/expression-list-in-functional-cast/
https://quuxplusone.github.io/blog/2022/06/03/aggregate-parens-init-considered-kinda-bad/

I think a proposal in that area — to make `T(x)` relatively "safer" through
a years-long process of *deprecating* the dangerous meanings — would be
helpful and appreciated.
We shouldn't touch the C-compatibility meaning of `(int)ptr`, for example;
but it doesn't seem there's any sensible reason for `int(ptr)` to exist.
Functional-style casts that are equivalent to reinterpret_casts could be
deprecated.
...Or could they? Today, I can write
    struct BigInteger { explicit BigInteger(void *ptr); };
    auto x = int(ptr); // OK, reinterpret_cast
    auto y = BigInteger(ptr); // OK, explicit conversion
but I believe if we restrict ourselves to keyword casts only, I'd be forced
to write non-generic code:
    auto x = reinterpret_cast<int>(ptr); // OK, reinterpret_cast
    auto y = static_cast<BigInteger>(ptr); // OK, explicit conversion
Any paper in this area would have to engage with that.

HTH,
Arthur

Received on 2023-12-30 14:54:31