<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Sep 13, 2017, at 11:07, Maciej Stachowiak <<a href="mailto:mjs@apple.com" class="">mjs@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="Apple-interchange-newline"><br class=""><blockquote type="cite" class=""><div class="">On Sep 13, 2017, at 8:11 AM, JF Bastien <<a href="mailto:jfbastien@apple.com" class="">jfbastien@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hello WebCritters,<div class=""><br class=""></div><div class="">I’m moving some code around, and one particular header I have is included everywhere in JSC so I’d like it to be lightweight and include as few other headers as possible. It unfortunately uses<span class="Apple-converted-space"> </span><font face="Courier New" class="">WTF::Vector</font>, but it only does so as a pointer:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><font face="Courier New" class="">void ohNoes(Vector<Noms>*);</font></div></blockquote><div class=""><br class=""></div><div class="">It seems like something a forward declaration would fix nicely, and oh joy and wonder we have<span class="Apple-converted-space"> </span><font face="Courier New" class="">Forward.h</font> just for this! Here’s what it does:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><font face="Courier New" class="">template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity, typename Malloc> class Vector;</font></div></div></blockquote><div class=""><br class=""></div><div class="">That’s nice and great for<span class="Apple-converted-space"> </span><font face="Courier New" class="">T</font>, but all the other template parameters are SOL because<span class="Apple-converted-space"> </span><font face="Courier New" class="">Vector</font><span class="Apple-converted-space"> </span>is actually declared with default template parameters:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><font face="Courier New" class="">template<typename T, size_t inlineCapacity = 0, typename OverflowHandler = CrashOnOverflow, size_t minCapacity = 16, typename Malloc = FastMalloc></font></div></div><div class=""><div class=""><font face="Courier New" class="">class Vector : private VectorBuffer<T, inlineCapacity, Malloc> {</font></div></div></blockquote><div class=""><br class=""></div><div class="">The extra painful thing is that, contrary to what I originally thought, one<span class="Apple-converted-space"> </span><i class="">cannot</i> declare <span class="" style="font-family: "Courier New";">Vector</span> in<span class="Apple-converted-space"> </span><font face="Courier New" class="">Forward.h</font> and then define it in <span class="" style="font-family: "Courier New";">Vector.h</span> with the same defaults twice! Ideally the compiler would just yell at a mismatch, but instead it says <font face="Courier New" class="">error: template parameter redefines default argument</font> (thanks clang, that’s exactly what I’m trying to do, just tell me if you catch a mismatch and ODR away otherwise).</div><div class=""><br class=""></div><div class="">Here’s what I propose:</div><div class=""><br class=""></div><div class=""><ol class="MailOutline"><li class="">Change the forward declaration in<span class="Apple-converted-space"> </span><font face="Courier New" class="">Forward.h</font> to contain the default template parameters (and forward-declare<span class="Apple-converted-space"> </span><font face="Courier New" class="">CrashOnOverflow</font>).</li><li class="">Remove these default template parameters from <span class="" style="font-family: "Courier New";">Vector.h</span>.</li><li class="">Include<span class="Apple-converted-space"> </span><font face="Courier New" class="">Forward.h</font> in <span class="" style="font-family: "Courier New";">Vector.h</span>.</li><li class="">Optionally, if the WebCritters think it useful, leave a comment just above the <span class="" style="font-family: "Courier New";">Vector</span> definition redirecting to<span class="Apple-converted-space"> </span><font face="Courier New" class="">Forward.h</font> for defaults (or more fancy, use<span class="Apple-converted-space"> </span><font face="Courier New" class="">size_t inlineCapacity /*=0*/</font> style like LLVM’s codebase does, and have a tool that checks for consistency).</li><li class="">Optionally, try to fix C++20 so this isn’t A Thing anymore. Note that my hopes are low because of modules (why fix it if modules will magically make this not a thing).</li></ol></div><div class=""><br class=""></div><div class="">Alternatively, I could just include <span class="" style="font-family: "Courier New";">Vector.h</span> and be done with it.</div><div class=""><br class=""></div><div class="">Thoughts?</div></div></div></blockquote><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Is there anything in Forward.h that should not be included everywhere you include Vector.h, whether for efficiency or any other reasons? That's the only potential thing I can think of that may be wrong with this plan. In that case, the simple fix would be to have a separate VectorForward.h which can be included by both.</div></div></blockquote><br class=""></div><div>I thought about that, and it seems like Forward.h is so tiny that it shouldn’t be an issue. If it ever starts including other WTF things then we should definitely do what you say, but I don’t think we should at the moment. Or put another way, if Forward.h doesn’t purely forward-declare things then it’s doing it wrong. :-)</div><br class=""></body></html>