--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFBACWbp58Bb1Pqs3-vGq8e_kBGRrgfSwLoLcLWjoLD6Hw%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CACwGi-5unDKweP9emrLXyMb%2BwveJp33xH550gH7y5cCnh_uHpQ%40mail.gmail.com.
Are there any gotchas with inline variables and component builds? We'd probably get a unique instance of each inline variable per component right?
Windows apparently requires the use of dllexport/dllimport for inline variables in DLLs (with the dllexport defined exactly once), which makes inline less useful:On Tue, Dec 28, 2021, 2:13 PM Will Cassella <cas...@chromium.org> wrote:I updated the test to also check shared objects, and it looks like the dynamic linker can coalesce weak symbols too, which is kind of neat. It almost certainly has some binary size overhead, and I have no idea how portable this behavior is, so still don't think I'd recommend using `static inline`. Definitely +1 for `static constexpr` though.
On Tuesday, December 28, 2021 at 1:18:08 PM UTC-8 Will Cassella wrote:Got linked to this thread from a CL fixing an instance of this, definitely agree that people will start using without even thinking about it, since I remember being initially shocked that this wasn't how `static constexpr` worked before.For the case of non-constexpr `static inline` variables, it seems the way this works is by generating a "weak" definition of the symbol in each translation unit that gets coalesced to a single definition during linking. I'd guess that if you're using shared objects with this you'll end up with a unique address for that variable in each component.
I think a PSA should include the fact that the `inline` keyword is implied when the variable is declared as `static consexpr`, and we probably shouldn't let people use `static inline`.I whipped up a simple test of what this all generates for anyone who's interested: https://github.com/willcassella/static-constexpr-testOn Friday, December 24, 2021 at 10:35:59 AM UTC-8 Peter Kasting wrote:On Fri, Dec 24, 2021 at 9:30 AM Daniel Cheng <dch...@chromium.org> wrote:Are there any gotchas with inline variables and component builds? We'd probably get a unique instance of each inline variable per component right?Honestly I'm not really sure how inline variables that aren't used as constants work. I'm trying to read cppreference.com on the subject, but it is not enlightening me. I mostly just want to have "static constexpr T" be the officially-approved way to do class-scope constants :(.PK
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CACwGi-4xAA2vZEYapZ6puyQmfcJMGPLib9SUF%2BtCN0cJ9OANcg%40mail.gmail.com.
On Wed, Dec 29, 2021 at 10:34 AM K. Moon <km...@chromium.org> wrote:Windows apparently requires the use of dllexport/dllimport for inline variables in DLLs (with the dllexport defined exactly once), which makes inline less useful:
On Tue, Dec 28, 2021, 2:13 PM Will Cassella <cas...@chromium.org> wrote:I updated the test to also check shared objects, and it looks like the dynamic linker can coalesce weak symbols too, which is kind of neat. It almost certainly has some binary size overhead, and I have no idea how portable this behavior is, so still don't think I'd recommend using `static inline`. Definitely +1 for `static constexpr` though.Why are static inline and static constexpr different in this regard? It's problematic for even constexpr variables to be ODR-used and the symbols not to be coalesced, because having the same variable have two different addresses is an ODR violation and thus undefined behavior.
constexpr
specifier used in a function or static data member (since C++17) declaration implies inline
."--It would be good to understand how this works in component builds across the dynamic linkers on Win, Mac and Linux (and I suppose also Fuchsia).On Tuesday, December 28, 2021 at 1:18:08 PM UTC-8 Will Cassella wrote:Got linked to this thread from a CL fixing an instance of this, definitely agree that people will start using without even thinking about it, since I remember being initially shocked that this wasn't how `static constexpr` worked before.For the case of non-constexpr `static inline` variables, it seems the way this works is by generating a "weak" definition of the symbol in each translation unit that gets coalesced to a single definition during linking. I'd guess that if you're using shared objects with this you'll end up with a unique address for that variable in each component.Don't constexpr ones work the same way? They still need to have a unique address even though their values are compile-time constants (they can still be ODR-used).--I think a PSA should include the fact that the `inline` keyword is implied when the variable is declared as `static consexpr`, and we probably shouldn't let people use `static inline`.I whipped up a simple test of what this all generates for anyone who's interested: https://github.com/willcassella/static-constexpr-testOn Friday, December 24, 2021 at 10:35:59 AM UTC-8 Peter Kasting wrote:On Fri, Dec 24, 2021 at 9:30 AM Daniel Cheng <dch...@chromium.org> wrote:Are there any gotchas with inline variables and component builds? We'd probably get a unique instance of each inline variable per component right?Honestly I'm not really sure how inline variables that aren't used as constants work. I'm trying to read cppreference.com on the subject, but it is not enlightening me. I mostly just want to have "static constexpr T" be the officially-approved way to do class-scope constants :(.PK
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CACwGi-4xAA2vZEYapZ6puyQmfcJMGPLib9SUF%2BtCN0cJ9OANcg%40mail.gmail.com.
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CACuR13dN7aEMnxU6taJoag2H5JSWQv1qTTGcmTYrOjdvbNy%3DTQ%40mail.gmail.com.
On Wed, Dec 29, 2021 at 5:50 PM Jeremy Roman <jbr...@chromium.org> wrote:On Wed, Dec 29, 2021 at 10:34 AM K. Moon <km...@chromium.org> wrote:Windows apparently requires the use of dllexport/dllimport for inline variables in DLLs (with the dllexport defined exactly once), which makes inline less useful:The answer from MS says:"you can remove the ‘__declspec(dllimport)’ specifier from the definition to fix the issue"Why would the use of dllexport/dllimport be required?
This writeup is interesting, as it directly discusses what Chrome does with inline functions (which existed pre-C++17):
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAAHOzFCgvO1OYEkwNpDUqcJtGkNY8UgCOXNubGsjvz_k_GVPcQ%40mail.gmail.com.
Why are static inline and static constexpr different in this regard?
The problem of multiple global definitions isn't purely unique to inline variables. We've had this problem in the past with things like //mojo, where some core //mojo code was being built as a source set, and then linked into multiple components.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAF3XrKqHCJsZNh9Y6-CScpH5vFkDBU1E6m3FkdGdihJrs7hE9A%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAFstQzPUo%2B6A03dLXkqTONeoCW0%2BgJCk%2BJN-94Cf3yvV-%2B86yQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAKLzqjE_bbZVVhV9eJaJzqJtH3X4EvkO%2BO3RSXAkK2QA-5myjQ%40mail.gmail.com.
We can still enforce certain restrictions with the clang plugins, such as disallowing taking the address of an inline variable.
--
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAFstQzNzVEyLRobq%2B-mUt0fJ%3DLxdncwQhPaCRBoLRbu0B-6goQ%40mail.gmail.com.
I was thinking about how you might update the clang plugin to address this (hah), and while you could probably catch simple cases like `&kInlineStatic` (by visiting `UnaryOp` expressions in the AST where `op == UO_AddrOf`, and then checking the decl of the argument), it would be much more difficult to catch cases like `&std::cref(kStatic).get()`. I don't think preventing implicit conversion of an inline constexpr variable to a const lvalue reference would work, since there's certainly legitimate uses for that.
Another route could be to require a wrapper type for inline constants like this, but then you would have to update the plugin to enforce use of that and it would be more cumbersome in cases where you want to plug that constant into a template argument, for example.So I don't know if the addressing problem in component builds can be 100% prevented with a plugin. I think we should allow inline constexpr variables, but note that if you expect them to have a consistent address across modules then you're just asking for trouble.One heuristic we could use is to catch if you try to define storage for an inline constexpr variable in a TU, since that might be a case where people are expecting the address to be consistent, and it has no real effect on the build with C++17 now anyway.
--On Tuesday, January 11, 2022 at 8:15:59 AM UTC-8 km...@chromium.org wrote:I think one of the tensions here is the constexpr case, which already became inline when the compiler flag was flipped to C++17. So this is already the status quo; the best time to have done this enforcement was before the C++17 flip.If someone is volunteering to do this as a fast follow, I think that would be a good compromise, but if nobody gets around to it for weeks or months, I don't think that makes sense.On Tue, Jan 11, 2022 at 6:42 AM <dan...@chromium.org> wrote:I think it's reasonable to block this on writing the clang plugin bits that will prevent breaking the component build. Doing so is not hard just takes a bit of effort/time, and it's important to avoid very confusing bugs later.On Mon, Jan 10, 2022 at 3:54 PM 'Honglin Yu' via cxx <c...@chromium.org> wrote:+1 after disallowing mutating and addressing.--On Tue, Jan 11, 2022 at 5:52 AM Daniel Cheng <dch...@chromium.org> wrote:Yes, we already have a clang plugin as part of the build: https://source.chromium.org/chromium/chromium/src/+/main:tools/clang/plugins/FindBadConstructsConsumer.cpp. I think we should try to add this preemptively sooner rather than later.DanielOn Fri, 7 Jan 2022 at 11:55, Peter Kasting <pkas...@google.com> wrote:On Fri, Jan 7, 2022 at 11:22 AM Daniel Cheng <dch...@chromium.org> wrote:We can still enforce certain restrictions with the clang plugins, such as disallowing taking the address of an inline variable.Do such plugins exist? I'm kinda uncomfortable blocking this on us writing one.PK
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/CAFstQzNzVEyLRobq%2B-mUt0fJ%3DLxdncwQhPaCRBoLRbu0B-6goQ%40mail.gmail.com.
You received this message because you are subscribed to the Google Groups "cxx" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cxx+uns...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/cxx/e2d77cc1-9cac-4e8c-853c-d8179324e234n%40chromium.org.
I would consider this check to be enough, anyway, along with a note like has been mentioned explaining the dangers.
I think this would be a good secondary thing to look for, along with the AddrOf check above.
If I'm following this correctly then we are currently compiling as C++17 on Windows which means that constexpr variables in header files should be folded together, at least in non-component builds, with some possible exceptions.A bug related to a constexpr variable in a header file getting multiple definitions (crbug.com/1269955) popped up for me yesterday. I just double-checked with today's 32-bit canary and it shows that there are still lots of duplicates. I thought it might be because the definition was in an anonymous namespace so I moved kOrderIndexShiftout of all namespaces and ShowGlobals still says we have a dozen copies of this array.Does the constexpr==inline variable logic only work for scalar variables perhaps?
constexpr
specifier used in a function or static data member (since C++17) declaration implies inline
.