<div dir="ltr">Hi Arthur,<div><br></div><div>First of all, it's an honor. I remember watching your "Allocator is a handle to a heap" c++now talk a while ago :)</div><div><br></div><div>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 <a href="https://en.cppreference.com/w/cpp/language/explicit_cast">the standard</a> 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: <a href="https://godbolt.org/z/5STynJ">https://godbolt.org/z/5STynJ</a>.</div><div><br></div><div>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}: <a href="https://godbolt.org/z/7LJCQy">https://godbolt.org/z/7LJCQy</a>. I will leave the union c-style casts as is for now(as clang trunk can't reproduce this even), and in the future hope to contribute a patch to remove this. Thank you for your input!</div><div><br></div><div>Best,</div><div>Ray</div><div><br></div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Jun 20, 2020 at 1:22 PM Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr">On Sat, Jun 20, 2020 at 3:31 PM Ray Zhang via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi all,<div><br></div><div>I'm currently implementing a clang tool to replace C style casts to C++ style casts, i.e. const/static/reinterpret_casts. I'm almost done, but I've ran into a collection of issues/questions that I'd like to raise here to make sure it's not a misunderstanding on my part. My solutions are included in each bullet point:</div><div><br></div><div>1. (Question) For dependent types, it is unknown whether static_cast or reinterpret_cast is appropriate for the situation, so I would like to leave that as a C-style cast in the refactor tool. Example below:</div><div><br></div><div><span style="color:rgb(28,30,33);font-family:monospace;font-size:15px;white-space:pre-wrap;background-color:rgb(253,245,212)">template <typename T>
void foo() {
int* ptr;
(T*) ptr;
}
</span><br></div><div>If we call foo<int>, it can be a const_cast, but if we call foo<double>, it has to be a reinterpret_cast.</div></div></blockquote><div><br></div><div>It could even involve both a const_cast and a static_cast; or it could be unrepresentable as a non-C-style cast (e.g. a cast to a private base).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div> In a situation where the user is writing library code, it won't only be relevant to the current translation unit but also for future purposes. Therefore, I propose that we leave dependent type c-style casts as they are.</div></div></blockquote><div><br></div><div>Sounds reasonable. Although, it would be nice to flag such casts for human inspection somehow; see my very informal proposal <a href="https://quuxplusone.github.io/blog/2020/01/22/expression-list-in-functional-cast/#it-would-be-useful-for-clang-or" target="_blank">here</a> for example.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>2. (Issue/bug) In OperationKinds.def, there is an enum detailing casting to union types. This doesn't work in clang(nor GCC). Here's a compiler explorer MVCE: <a href="https://godbolt.org/z/rp8DDt" target="_blank">https://godbolt.org/z/rp8DDt</a>. The first statement is <i>not a cast</i>, but rather a CompoundLiteralExpr(InitListExpr(...)), and should not be treated as a cast. Here is the corresponding GCC document: <a href="https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html" target="_blank">https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html</a> about union casts. If CastKind::CK_ToUnion is ever encountered in my program, I will leave the C-style cast as is.</div></div></blockquote><div><br></div><div>It works in GCC trunk for me... but only in C++20 mode.</div><div><a href="https://godbolt.org/z/Qjpxga" target="_blank">https://godbolt.org/z/Qjpxga</a><br></div><div>I suspect that your analysis is still correct: this feature is documented, but does not work, in GCC pre-C++20, and then in C++20 the changes around parens-initialization of aggregates broke it in such a way that now it <i>appears </i>to work but nobody should trust it to <i>actually </i>work. It might be nice to submit a patch ripping this broken stuff out of Clang and/or out of GCC.</div><div><br></div><div>my $.02,</div><div>–Arthur</div></div></div></div>
</blockquote></div>