C++ Weekly - Ep 382 - The Static Initialization Order Fiasco and C++20's constinit

Поделиться
HTML-код
  • Опубликовано: 25 июн 2023
  • ☟☟ Awesome T-Shirts! Sponsors! Books! ☟☟
    Upcoming Workshop: Understanding Object Lifetime, C++ On Sea, July 2, 2024
    ► cpponsea.uk/2024/sessions/und...
    Upcoming Workshop: C++ Best Practices, NDC TechTown, Sept 9-10, 2024
    ► ndctechtown.com/workshops/c-b...
    Upcoming Workshop: Applied constexpr: The Power of Compile-Time Resources, C++ Under The Sea, October 10, 2024
    ► cppunderthesea.nl/workshops/
    Discussion: github.com/lefticus/cpp_weekl...
    T-SHIRTS AVAILABLE!
    ► The best C++ T-Shirts anywhere! my-store-d16a2f.creator-sprin...
    WANT MORE JASON?
    ► My Training Classes: emptycrate.com/training.html
    ► Follow me on twitter: / lefticus
    SUPPORT THE CHANNEL
    ► Patreon: / lefticus
    ► Github Sponsors: github.com/sponsors/lefticus
    ► Paypal Donation: www.paypal.com/donate/?hosted...
    GET INVOLVED
    ► Video Idea List: github.com/lefticus/cpp_weekl...
    JASON'S BOOKS
    ► C++23 Best Practices
    Leanpub Ebook: leanpub.com/cpp23_best_practi...
    ► C++ Best Practices
    Amazon Paperback: amzn.to/3wpAU3Z
    Leanpub Ebook: leanpub.com/cppbestpractices
    JASON'S PUZZLE BOOKS
    ► Object Lifetime Puzzlers Book 1
    Amazon Paperback: amzn.to/3g6Ervj
    Leanpub Ebook: leanpub.com/objectlifetimepuz...
    ► Object Lifetime Puzzlers Book 2
    Amazon Paperback: amzn.to/3whdUDU
    Leanpub Ebook: leanpub.com/objectlifetimepuz...
    ► Object Lifetime Puzzlers Book 3
    Leanpub Ebook: leanpub.com/objectlifetimepuz...
    ► Copy and Reference Puzzlers Book 1
    Amazon Paperback: amzn.to/3g7ZVb9
    Leanpub Ebook: leanpub.com/copyandreferencep...
    ► Copy and Reference Puzzlers Book 2
    Amazon Paperback: amzn.to/3X1LOIx
    Leanpub Ebook: leanpub.com/copyandreferencep...
    ► Copy and Reference Puzzlers Book 3
    Leanpub Ebook: leanpub.com/copyandreferencep...
    ► OpCode Puzzlers Book 1
    Amazon Paperback: amzn.to/3KCNJg6
    Leanpub Ebook: leanpub.com/opcodepuzzlers_book1
    RECOMMENDED BOOKS
    ► Bjarne Stroustrup's A Tour of C++ (now with C++20/23!): amzn.to/3X4Wypr
    AWESOME PROJECTS
    ► The C++ Starter Project - Gets you started with Best Practices Quickly - github.com/cpp-best-practices...
    ► C++ Best Practices Forkable Coding Standards - github.com/cpp-best-practices...
    O'Reilly VIDEOS
    ► Inheritance and Polymorphism in C++ - www.oreilly.com/library/view/...
    ► Learning C++ Best Practices - www.oreilly.com/library/view/...
  • НаукаНаука

Комментарии • 52

  • @anon_y_mousse
    @anon_y_mousse Год назад +10

    This is cool. I didn't know that CE had a project mode. Can you share projects that way? It'd certainly be a neat way to share larger examples.

    • @cppweekly
      @cppweekly  Год назад +1

      Can share the same as any other link, yeah.

  • @luppy42
    @luppy42 Год назад +1

    I believe it is worth to mention that the initialization of inline variables (C++17) are partially ordered, they can depend on each other which makes them viable to implement global services (e.g. allocators, debug helpers).

  • @KhalilEstell
    @KhalilEstell Год назад

    Another great video Jason!

  • @aibou2399
    @aibou2399 Год назад

    Nice Video. And that CE mode seems useful

  • @me2tal
    @me2tal Год назад

    I'm glad I've never had to worry about this sort of circumstance..
    Also, I would say you could easily have gone with a small font size in CE. Would make it a little easier to read the cramped windows.

  • @necro_ware
    @necro_ware 6 месяцев назад

    That's why I always use singleton pattern in case I ever need a global object at all, so it is constructed on the first call and not before main. If I need early init I just can call it from somewhere early in the program. Of course this also means additional mutex and/or atomic access, but everything has a price and global objects should be avoided anyway.

  • @andreyk.503
    @andreyk.503 Год назад +1

    Is there a way to request constinit'ness in consumer?
    Like if provider was in a third party library and I need to know if I can use this library objects safely, e.g. in code executed when my shared library is loaded?

  • @markspieth7591
    @markspieth7591 Год назад

    Interesting portable way especially if it resolves heirarchical dependencies. I have been using the constructor attribute for years to control global construction/init sequencing in the embedded world, but this is certainly not portable, but it doesn't require the class constructor to be constexpr.

  • @TsvetanDimitrov1976
    @TsvetanDimitrov1976 Год назад +3

    I mean it's nice to have that fixed, but static globals are code smell anyway.

    • @bloodgain
      @bloodgain Год назад +2

      You're absolutely right, but sometimes you get stuck with legacy code that is chock full of mutable global state, and this can at least get you out of a quagmire while you work toward eliminating it one piece at a time. As someone else mentioned, replacing it with a Meyers (Leaky) Singleton pattern can also resolve the SIOF, and while Singleton is still usually a bad idea, it gives you back some control over construction.

  • @dimon_ksi
    @dimon_ksi Год назад

    We can put such objects in one struct and make that struct object to be global. This guaranties the initialization order of members.

    • @dimon_ksi
      @dimon_ksi Год назад

      Anyway thanks for this episode. This was useful to know.

  • @yb9737
    @yb9737 Год назад +4

    What if there are multiple statics which need to be static initialized with constinit ?what will be the order then ?

    • @ajinkyakamat7053
      @ajinkyakamat7053 Год назад +3

      The order should be automatically resolved correctly. Remember you can only use constexpr variables at compile time and u can't declare but not initialize constexpr variables.

    • @ohwow2074
      @ohwow2074 Год назад +3

      They're initialized at compile time. The compiler will figure out the order.

    • @yb9737
      @yb9737 Год назад +1

      Ok thanks

  • @baardi2
    @baardi2 Год назад +4

    I know about Kongsberg in Norway, but never knew there was a Kongsberg in Sweden as well

    • @oschonrock
      @oschonrock Год назад

      Kongsberg, formerly spelled Konningsberg (lit. "King's Mountain"), (wikipedia)

    • @md2perpe
      @md2perpe Год назад +1

      Same here. And I'm Swedish.

    • @oschonrock
      @oschonrock Год назад

      @@md2perpe I think he mispoke anyway

  • @reductor_
    @reductor_ Год назад

    There is actually a well defined way to ensure the order they are initialized in, define them within the same TU. (e.g. make a globals.cpp)

    • @BryceDixonDev
      @BryceDixonDev Год назад +1

      That would then require a globals.h with tons of `extern`s which IMO is a code smell (global state probably shouldn't ever be a thing anyway)

    • @reductor_
      @reductor_ Год назад +1

      @@BryceDixonDev no it doesn't, the externs can be anywhere. While eliminating global state is ideal in some cases it provides greater flexibility and cleaner code (with cavets around testing and threading)

  • @surrog
    @surrog Год назад +1

    Still feel that putting global in function is superior than constinit, but it's nice to have alternative approach

    • @cppweekly
      @cppweekly  Год назад

      I feel like those are two different options. Personally, if I know the thing *can* be initialized before runtime, I want it to be!

  • @userrand4900
    @userrand4900 11 месяцев назад

    Is the guarantee here that constinit does not modify compiler behavior in any way (i.e. removing them at the end in this case was OK) ? IOW it always serves to *validate* compiler behavior for the case when you have constexpr constructors.

    • @cppweekly
      @cppweekly  11 месяцев назад

      constinit changes nothing. It just provides a guarantee that your assumptions are correct.

  • @rafalmichalski4893
    @rafalmichalski4893 Год назад

    How can we link to gtest in this view ? How to update CMake ?

  • @rafalmichalski4893
    @rafalmichalski4893 Год назад

    How to add new files in this CMake view ?

  • @homomorphic
    @homomorphic Год назад +14

    Are you saying "constinint" or are my ears broken?

  • @ABaumstumpf
    @ABaumstumpf 11 месяцев назад

    Seems like this is only useful in aesotheric and fictional code:
    It works if Global A depends on Global B, and B can be constexpr constructed.
    If there are more than 2 globals involved? Supposedly magic happens.
    If any of the depended-on globals does not have a constexpr-constructor? Doesn't work.
    "constinit" seems to try to work on too many problems and fails to plug many of the holes. It really only should be used for marking variables that need to be const-initialised... and even at that it is not good cause that can and will still happen at runtime - the only guarantee the language really makes is that it it evaluated before all dynamic initialisation - aka before main is called - but it says absolutely nothing about whether it is done at compiletime or not (just most compilers try to do it at compiletime when they can resolve it)

    • @cppweekly
      @cppweekly  11 месяцев назад

      It just provides a compile-time guarantee that you didn't have previously.

  • @dagoberttrump9290
    @dagoberttrump9290 Год назад

    I will also hate anybody that overloads &. It's just so unexpected even if you know about the possibilities...

  • @mworld
    @mworld Год назад

    Not sure if anyone's mentioned it, but your audios volume is low in this and other videos of yours :)

    • @cppweekly
      @cppweekly  11 месяцев назад

      Thanks, I just recently tweaked my process. The coming up videos should have better levels.

  • @hampus23
    @hampus23 Год назад +3

    0:31 Norway 😂

  • @polyontomorphic
    @polyontomorphic 8 месяцев назад

    Why do you say that constinit does nothing to the "meaning" of the code when it avoids the implementation-defined behavior of static initialization? constinit changes the output of the compiler because now initializing provider first does not depend on the order of the translation units, so the meaning has changed (at least one could say the semantics or meaning has changed in the case of the incorrect order of translation units).

    • @cppweekly
      @cppweekly  8 месяцев назад

      No, constinit does *not* change the output of the compiler. All it does is ensure that your assumptions are correct. Static initialization rules are required by the standard.
      if you have an example that proves me wrong, please open a new issue: github.com/lefticus/cpp_weekly/issues so I can do a follow up episode

    • @polyontomorphic
      @polyontomorphic 8 месяцев назад

      @@cppweekly constinit merely requires constexpr, which changes meaning. Your example works to show the point, but it adds both specifiers at the same time.
      without constinit, provider before consumer leads to output:
      clang++ provider.cpp consumer.cpp main.cpp -std=c++20
      "Hello there World!?"
      without constinit, consumer before provider leads to no output:
      clang++ consumer.cpp provider.cpp main.cpp -std=c++20
      ""
      with constinit, consumer before provider leads to output:
      clang++ consumer.cpp provider.cpp main.cpp -std=c++20
      "Hello there World!?"
      The last two points emit different binaries, and the only difference is the constinit on Provider and thus the constexpr on its ctor. Inspecting further, only the constexpr is required to get "consumer before provider" to give output, so this is the actual semantic change to the meaning of the code.

  • @Solarbonite
    @Solarbonite Год назад

    Oof. I normally prefer the Myers Leaky Singleton pattern. But that's for things like loggers or root exception handlers for poll() based multithreaded code. You know that it won't exist until you call it and that it will never invoke a destructor.

  • @nicholaskomsa1777
    @nicholaskomsa1777 2 месяца назад

    I would argue that if you are encountering these race conditions or thinking about how they work, then you could use refactoring instead.

    • @cppweekly
      @cppweekly  2 месяца назад

      If you use global statics, you have to worry about this. If you have interactions between static and thread_local, you have to worry about this.

    • @nicholaskomsa1777
      @nicholaskomsa1777 2 месяца назад

      @@cppweekly yeah, but then you also have to resolve it all somehow. Probably by refactoring out of the race-conditions to start.

  • @brynyard
    @brynyard Год назад

    Woot, the Swedes have invaded Kongsberg?!

  • @oschonrock
    @oschonrock Год назад +2

    Nice. You say "two statics which depend on each other", but neither of them is declared as static...

    • @sledgex9
      @sledgex9 Год назад +5

      Global variables have static storage duration in C++. Same goes for variables marked with extern.

    • @oschonrock
      @oschonrock Год назад

      @@sledgex9 yes,, I know that, but it may not have been so clear for everyone

  • @oleholgerson3416
    @oleholgerson3416 Год назад +1

    Absolutely only a gimmick, I really dont see any real world value. Focus on the core basics and make them really well