[cfe-dev] Questions/discussions about cast types in clang

Ray Zhang via cfe-dev cfe-dev at lists.llvm.org
Sat Jun 20 15:43:31 PDT 2020


Hi Arthur,

Regarding the static_cast extension - I see how I can reproduce that now.
Thank you! For each DerivedToBase cast type, I'll check to see whether the
base class is inaccessible, and leave the C-style cast as-is.

:facepalm: at not reading the first sentence of that GCC document. I had
the assumption that all C extensions were available in C++ for backwards
compatibility, but today I learned. Sorry about the wild goose-chase! The
enum CastKind::CK_ToUnion is thus referring to a feature from a C extension
not yet available(will it ever be available?) in C++, I'll try to document
it in my tool and later in the enum definitions.

Learned a lot from our discussion, thanks so much!

Best,
Ray

On Sat, Jun 20, 2020 at 3:19 PM Arthur O'Dwyer <arthur.j.odwyer at gmail.com>
wrote:

> On Sat, Jun 20, 2020 at 5:33 PM Ray Zhang <peifeng2005 at gmail.com> wrote:
>
>> Hi Arthur,
>> First of all, it's an honor. I remember watching your "Allocator is a
>> handle to a heap" c++now talk a while ago :)
>>
> Hey, thanks! :) Don't take anything I say as gospel when it comes to
> cfe-dev, though. :)
>
> Second, you're right - I forgot about DerivedToBase or BaseToDerived in
>> the above example. Regarding the statement regarding unpresentable as a
>> non-C-style cast, in the standard
>> <https://en.cppreference.com/w/cpp/language/explicit_cast> it breaks
>> down C-style casts as a cascading attempt to use const/static/reinterpret,
>> or combinations of them. Here's an example of private base:
>> https://godbolt.org/z/5STynJ.
>>
>
> Yes, but notice where cppreference says "static_cast *with exceptions*";
> I was talking about the exceptions.
> Here's an example where C-style cast and reinterpret_cast do different
> things, but any other kind of cast (e.g. static_cast) is ill-formed.
> https://godbolt.org/z/if7Pis
> Clang gives a warning suggesting that you replace the reinterpret_cast
> with a static_cast, but of course if you actually did that, the code
> wouldn't compile anymore.
>
>
> Third, I didn't check for C++20 for union casts, but I'm guessing it
>> "working" is a side-effect of the parens-initialization of aggregates
>> allowing narrowing conversions. Here's a link that shows that the example
>> in the C++20 mode you showed is not equivalent to a C-style cast assignment
>> which is just an alias for (union U) {.x = x}:
>> https://godbolt.org/z/7LJCQy.
>>
>
> Ah, yes, you're right. With `(U)y`, GCC is calling the same
> pseudo-constructor as `U(y)`, which is supposed to just implicitly convert
> the float to an int and initialize the first member of the union,
> completely ignoring the fact that `y` is a float
> This appears to be actually the correct behavior in C++20, even though it
> seems pretty crazy. (In other words, C++20's new union syntax doesn't
> follow the same overload-resolution-ish rules as C++17's std::variant.)
> Textual support:
> http://eel.is/c++draft/expr.cast#4 says that (U)y should behave the same
> as static_cast<U>(y) if possible, and
> http://eel.is/c++draft/expr.static.cast#4 says that static_cast<U>(y)
> should behave the same as U(y), which (new in C++20) should behave the same
> as U{.x = y}.
>
> Here's a pared-down example where the two fields of the union have utterly
> different types, so the silent implicit conversion fails instead of
> succeeding. https://godbolt.org/z/9wVX6B
> Apparently Clang just doesn't implement this C++20 rule yet; once it does,
> Clang's behavior should end up matching GCC's.
>
> ...Oh, and wait a minute! The first sentence of the documentation you
> linked says, "A cast to a union type is *a C extension not available in
> C++*."  So that explains why neither of us could reproduce the documented
> behavior! :)  Now here's a Godbolt showing the same code compiled as C++
> (where it initializes the first field of the union) and C-with-extensions
> (where it initializes the second field because that field is a float).
> https://godbolt.org/z/heN2Fb
> And here's Clang, reproducing GCC's behavior in C-with-extensions but
> failing to implement C++20 yet:
> https://godbolt.org/z/dY6ti8
>
> –Arthur
>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200620/6368dc59/attachment.html>


More information about the cfe-dev mailing list