C++ Weekly - Ep 322 - Top 4 Places To Never Use `const`

Sdílet
Vložit
  • čas přidán 2. 06. 2024
  • ☟☟ 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...
    Episode 317 - Do You Really Understand Member Functions? - • C++ Weekly - Ep 317 - ...
    Episode 123 - Using in_place_t - • C++ Weekly - Ep 123 - ...
    Code Samples - compiler-explorer.com/z/9Wcc5...
    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/...
  • Věda a technologie

Komentáře • 82

  • @aDifferentJT
    @aDifferentJT Před 2 lety +21

    #2 and #3 are basically the same thing, don’t const values that are going to be returned. This is basically a subset of the rule not to const things that are going to be moved.

  • @ekondis
    @ekondis Před 2 lety +10

    #1 sounds disappointing. I find of value to set a member variable to be const when you are intending not to modify it. This is a negative side effect.

  • @sirhenrystalwart8303
    @sirhenrystalwart8303 Před 2 lety +10

    Thank you for #1! I get into arguments all the time with people at work when they want me to const member variables. Now I have a solid resource to point them to from a respected authority.

  • @kethernet
    @kethernet Před 2 lety +37

    I'd say 5) Don't take by const reference if you need to keep the value. I see a lot of reflexive `const std::string&` arguments where the string is then copied inside the function. `std::string` in that case is better, since it can be moved into the function, then moved where it needs to go. Perfect forwarding, or adding an overload of `std::string&&` work too.
    Also, with C++17, there's really no reason for `const std::string&`. Just take `std::string_view`.

    • @baardi2
      @baardi2 Před 2 lety +9

      There's a few reasons I can think of, e.g. when passing it in to an api taking null-terminated strings.

    • @ChiliTomatoNoodle
      @ChiliTomatoNoodle Před 2 lety +4

      @@baardi2 Yup, std::string_view with null-terminated strings is a pretty annoying combination.

    • @ajinkyakamat7053
      @ajinkyakamat7053 Před 2 lety +3

      Another reason you might not want to do "std::string const &" is exceptions. Though rare, if the copy fails and raises an exception your function is not exception safe. But taking a copy means that the exception happens outside your function and u just move it to where you want inside the function.

    • @friedkeenan
      @friedkeenan Před 2 lety

      @@baardi2 I hope in the future a sort of "zstring" (the term for a view of a string that's null-terminated) can become part of the STL

    • @_RMSG_
      @_RMSG_ Před 2 lety

      @@ChiliTomatoNoodle What about adding the null terminator when passing to those APIs? does that defeat the efficiency afforded by string_view?

  • @alagner88
    @alagner88 Před 2 lety +8

    Note that returning const value (4) had been advised (e.g. by Scott Meyers) before C++11 and its overloading on value category was introduced in order to prevent assignment to rvalues. Granted, it is hard to defend nowadays but imho still worth to keep it in mind especially when dealing with legacy code.

  • @FF_Fanatic
    @FF_Fanatic Před 2 lety +1

    I was close. I thought for sure that #2 was going to be "don't top-level const parameters in a forward declaration", but it was more an extension of #3, and my version of #3 was "don't const things that you intend to be moved from".

  • @DmitryReshitko
    @DmitryReshitko Před rokem +4

    Just came across with this video. Very helpful, but #1 looks like a "premature optimization". Using const for your members is not a typo, but part of the expressiveness and semantics of your code. So it is worth to mentioning that this is a tradeoff, and if your class can be moved and you are concerned about performance, then removing const will help.

    • @TrueWodzu
      @TrueWodzu Před 8 měsíci

      Exactly, it is a bummer that you lose some performance just because you want to have your member const, but it is a cost I am willing to take, to make my code cleaner.

    • @fullaccess2645
      @fullaccess2645 Před 7 měsíci

      @@TrueWodzu why not make a CONST macro and define it only on debug build? Wouldnt that be ideal?

  • @DamianReloaded
    @DamianReloaded Před 2 lety

    Great insight. 10/10

  • @joeblinx4379
    @joeblinx4379 Před 2 lety +3

    Hi!
    In your #1 point "Do not const member variables", I'm surprised that you didn't talk about "reference member variables" since a reference is a "non assignable" variable, it can be consider as a "const member variable" with some other drawback like the implicit deletion for copy and move assignment and not just the move one.

    • @viniciusferrao
      @viniciusferrao Před 2 lety

      I was expecting some info regarding this, although I think this is out of context on the video. But a note is definitely appreciated.

    • @cppweekly
      @cppweekly  Před 2 lety

      Yes, you're both correct, and I also avoid reference member variables, but not the point of this video.

  • @fcolecumberri
    @fcolecumberri Před 2 lety +5

    about #2, how many times do you create a function that receives an object that wont be changed and you just returns it? (non-rhetorical serious question)
    I mean, if you change it, it can't be const rendering this point useless
    but if you don't change it why do you returns it? outside the function the user of the function already has the object.

    • @User-cv4ee
      @User-cv4ee Před 2 lety +1

      Convinience? Especially if the object has complex initialization and we don't want code duplication.

    • @cppweekly
      @cppweekly  Před 2 lety +4

      You might have a conditional that says "return some new thing or returned the thing that was passed into me", but I agree this would be very rare. It's just a thing to be aware of.

    • @fcolecumberri
      @fcolecumberri Před 2 lety

      @@cppweekly that's a great answer.

  • @TrueWodzu
    @TrueWodzu Před 8 měsíci

    If I would follow every single rule that Jason defined over the years I would never finish a decent C++ program. It is good to know that such things exist but on the other hand you have customers and deadlines to meet.

  • @forgetfulfunctor1
    @forgetfulfunctor1 Před 2 lety

    the first example sounded almost like "use copy elision", except...
    is he saying that if we don't use copy constructor, and we do have a const return type, then the compiler uses copy ASSIGNMENT rather than move assignment?

  • @yash1152
    @yash1152 Před rokem +1

    7:27 whats clang-tidy?

  • @kimhyunpil
    @kimhyunpil Před 2 lety

    Thanks video

  • @calebtaylor8472
    @calebtaylor8472 Před rokem +1

    Is it worth avoiding const data members of a class if it isn't copyable at all?

    • @cppweekly
      @cppweekly  Před rokem +2

      if you have explicit disabled copy and move, then it's irrelevant

  • @raakakadaaka
    @raakakadaaka Před 9 měsíci +1

    This may seem a bit of a silly (and unrelated) question and I've tried looking out for answers and haven't gotten any. Is it possible to run Compiler Explorer on my code locally? I know I can generate the assembly instructions and all but it's not the same as having it side by side moving with your code. Or is it? That's what I wanna know, Thanks!

    • @cppweekly
      @cppweekly  Před 9 měsíci +2

      You certainly can, set up a local instance and include your own directories. It's a bit tricky sometimes, but should work out.

    • @raakakadaaka
      @raakakadaaka Před 9 měsíci

      @@cppweekly thanks Jason, I’ll give that a shot.

  • @TryboBike
    @TryboBike Před rokem

    Regarding rule #1.
    What about classes/structures which explicitly define move assignment and constructor?

    • @cppweekly
      @cppweekly  Před rokem

      It would be hard to do anything meaningful and correct in them, and the complication is probably not worth the effort.
      But it's theoretically possible there's a use case there.

    • @TryboBike
      @TryboBike Před rokem

      @@cppweekly
      I ask because rule #1 throws some sand at what I do at work. In essence - the use case is that I pass around lots and lots of structs. Which were classes before I dug into it. Basically - what I pass and/or return are structs which have all the data members public _and_ const for ease of access. Each struct defines copy/move operator and a matching constructor. If you want a new one, you are supposed to construct one either from scratch or by destroying an older one.
      The operators themselves are defined as an explicit call a destructor followed by placement 'new' and a move/copy constructor respectively. It _seems_ that MS compiler does make moves of std::strings in this case but debugging standard library is ... challenging.
      Now - I admit, I may have overthought this. But I like my m_foo.m_bar.m_member instead of m_foo->GetBar()->GetMember(). From profiling this code I get nice speedups as well.

  • @matinjalali4409
    @matinjalali4409 Před 2 lety

    U r the best👌

  • @negidrums915
    @negidrums915 Před 2 lety +1

    Is there any case we must use const to avoid performance issue (not human error)?

    • @deanjohnson8233
      @deanjohnson8233 Před 2 lety +2

      Only in very rare circumstances. Almost always, the compiler will make its own determination about what is const and what is not by analyzing the code and will optimize based on that regardless of whether you explicitly use const. One case I can think of where const may have a performance benefit is with global values used across translation units. In this situation, the compiler isn’t going to be able to analyze all usages of the variable and so it has to assume that it is non const. If you explicitly mark it as const, the compiler can trust you and use that for some additional optimizations.

    • @cppweekly
      @cppweekly  Před 2 lety +2

      Even without multiple translation units, if you mark a static (implicit or explicit) variable const, the compiler can move it to "static initialization" which means you can see a whole range of possible optimizations.
      I demonstrated this in my CppCon talk czcams.com/video/zBkNBP00wJE/video.html

  • @dagoberttrump9290
    @dagoberttrump9290 Před rokem

    can't you move construct const values? Granted that you write your own move constructor, I would say it's not too bad to have const members no?

    • @cppweekly
      @cppweekly  Před rokem

      you can `const auto value = std::move(othervalue)`
      but you cannot `const auto value = std::move(someconstvalue)` in any way that makes logical sense.

  • @xaxi5
    @xaxi5 Před 2 lety

    All effects are fully expected. This video just demonstrates the selected compiller works by standard. It's more interest to see is there some compillers or options to break expectations?

  • @vladimir0rus
    @vladimir0rus Před 4 měsíci

    Is it possible to detect all such cases automatically?

    • @cppweekly
      @cppweekly  Před 3 měsíci +1

      not with any tools that I know of.

  • @yash1152
    @yash1152 Před rokem

    0:51 any reason why you are using struct objects rather than class objects?

    • @cppweekly
      @cppweekly  Před rokem

      It makes the code shorter for my purposes.
      But it's important to know that there is no real difference between the two in C++. It's mostly a style a choice.

    • @yash1152
      @yash1152 Před rokem

      @@cppweekly not totally related, but not totally unrelated either:
      * have u attended/watched the talk about cpp2 titled "Can C++ be 10x Simpler & Safer? - Herb Sutter - CppCon 2022"
      * to me, it seems its syntax is so similar to Kotlin
      * but anyways, what are your thoughts on that approach/direction?

  • @Dizintegrator
    @Dizintegrator Před 2 lety

    If I dont const ANY member data, this would ultimately result into not using const member functions... So "Almost never use const" then? ;)

    • @cppweekly
      @cppweekly  Před 2 lety

      100% the wrong take away here. Const member functions have literally nothing to do with const member data *at all*
      you need to watch my last video on const member functions czcams.com/video/bqd9ILyQRxQ/video.html

  • @milasudril
    @milasudril Před 2 lety +1

    Strictly speaking, moving from an object may break an invariant:
    template
    struct WithAtLeastOne{
    explicit WithAtLeastOne(typename Container::value_type&& obj) {
    data.push_back(std::move(obj));
    }
    private:
    Container data;
    };
    ??

    • @alagner88
      @alagner88 Před 2 lety

      Isn't that the moment when rule of 5 should be used instead of relying on default implementations?

    • @SonicFan535
      @SonicFan535 Před 2 lety

      In this case, you could implement your move operations in terms of swap() to avoid breaking the invariant. Doing so would still conform to the standard recommended practice of leaving your moved-from object in a "valid, but unspecified" state.

  • @Pi03k
    @Pi03k Před 2 lety +2

    const first

  • @videojeroki
    @videojeroki Před 2 lety +8

    When you pick C++ for performance reasons and you find out that a single trivial const "error" make your effort irrelevant...

    • @ChaotikmindSrc
      @ChaotikmindSrc Před 2 lety +6

      I wouldn't go that far, it is certainly better to be aware of that, but you can still get very good perf comparing to other languages

    • @videojeroki
      @videojeroki Před 2 lety +4

      @@ChaotikmindSrc yes i exagerate a bit but you get my point ;)
      I love c++, not because it is great, just because i grew up with it. if i would start from scratch today, not sure i would pick it ^^

    • @ChaotikmindSrc
      @ChaotikmindSrc Před 2 lety

      @@videojeroki Oh well i can relate to that
      i would hope for an utopic world where some of the c++ horrors just go aways XD
      The language really feels over-engineered at the moment.

    • @videojeroki
      @videojeroki Před 2 lety

      @@ChaotikmindSrc Usually i try to code as clean as possible to make the optimization as simple as possible (preferably someone else) .
      sometime simple code looks like over engineered indeed. So hopefully this code is pushed and never seen again :D

    • @ChaotikmindSrc
      @ChaotikmindSrc Před 2 lety +1

      @@videojeroki I come from a darker place where i was reading assembly before taking a coffee and programming until the sun appears while drinking whisky.
      Took a long time for me to write "clean code" YMMV
      I'm partly healed tho ;)

  • @dennisrkb
    @dennisrkb Před 10 měsíci

    Never make your member variables const, they prevent moving. If you don't want anybody to change your members, make them private and only offer const public member functions.

    • @cppweekly
      @cppweekly  Před 9 měsíci

      Yup, that's in the video.

  • @originalmiu
    @originalmiu Před 2 lety +1

    Note: If you remove the puts() calls from struct S constructors and destructors, the compiler can optimize-away many of the bad uses of const. The puts() calls themselves are causing I/O, which forces the compiler to follow the C++ language rules for which ctors/dtors are logically called, to determine the correct output of the program. In other words, the puts() calls you're using for debugging this are causing the extra work, and not the bad const's.

    • @cppweekly
      @cppweekly  Před 2 lety +1

      You are over thinking this.
      The real point you are trying to make is that none of this matters if the types are trivial, which is a fact. I even did an entire conference talk about this specific topic:
      czcams.com/video/ZxWjii99yao/video.html

  • @hanyanglee9018
    @hanyanglee9018 Před 2 lety

    OK cool, thanks. Probably this is also one of the major difference from c++ with almost all the other languages. I remember in at least js and python, people are recommended to use const as possible, but const seems not to help in cpp. They are too different.
    Probably anything like 4 to 20 bytes can be const without any significant trouble because their ctor or copy are almost the same size, but if the object is bigger, then I guess the const keyword messes.

    • @cppweekly
      @cppweekly  Před 2 lety +2

      As I started the video with, you should use const almost everywhere. These are the exact 4 times to NOT use const. They help with readability, correctness, and in some places performance.

    • @hanyanglee9018
      @hanyanglee9018 Před 2 lety

      @@cppweekly OK. Thanks. I've been away from c++ for years. I saw people battle with the grammars with these tricks only to get the compiler to do specific jobs. If people can script for the compiler and specify the concrete behavior for the compiler, most the tricks against the compiler would be gone. I remember in another video, you mentioned the constexpr causes a lot trouble. If it had another layer, it would be like:
      {"compiler instructions";
      compile_time_const.push_back("some_variable")
      }
      int main(){
      const int some_variable = make_value(...);
      }
      I tried to tell people of this idea but no one cares.

  • @anon_y_mousse
    @anon_y_mousse Před 2 lety

    Looks like YT deleted my comment, but the gist of it was, I love your videos because they help me learn more about C++ and keep my skills with it up to date. However, they also give me more ammunition in my crusade against C++ because it is still a language I vehemently dislike. I wish more people would just use C and for fancy syntactic sugar, create a language that's better than C++, so not Rust.

    • @yash1152
      @yash1152 Před rokem

      have u watched the video about cpp2 presented in cpp-con2022 which talked about backword compatibility only on demand. It was solid.

  • @atillakayrak4293
    @atillakayrak4293 Před 2 lety

    It's crazy that a 2022 compiler is not smart enough to know that a local const value which will be be out of scope on return should be moved

    • @cppweekly
      @cppweekly  Před 2 lety +2

      you cannot MOVE a CONST because it is a Constant!
      At best it could be elided, but never ever moved. czcams.com/video/ZKaoR3dP9uM/video.html

  • @_RMSG_
    @_RMSG_ Před 2 lety

    I can't wait to use const in all of these places

  • @stevewilson5546
    @stevewilson5546 Před 2 lety

    C programmers are sadistic masochists. I didn't realize there were so many ways you could break the code. I'll stick with Turbo Pascal for short programs and Delphi for larger programs (minus Object programming, of course.)

  • @chololennon
    @chololennon Před 2 lety +3

    This language is really really awful (and before anyone says something about it, I have been programming professionally in C++ for more than 30 years). I can't believe that for every sentence I write I have to check what the compiler emits at low level 😱

    • @deanjohnson8233
      @deanjohnson8233 Před 2 lety +9

      Nothing forces you to check this. Other compiled languages are going to have similar issues where a small change can drastically change the compiled representation. I see plenty of videos just like this for c# that explore how tiny changes can have huge impacts on the generated code. IMO, this is the reality of compiled languages - they tend to be so much higher level than what they compile into that you are going to have these kinds of situations.
      I think we talk about these issues in c++ more because c++ programmers tend to love to squabble about low level optimizations like this.
      I haven’t reached your level of experience yet, but in my 12 years of c++ experience I have never looked at the generated assembly of something I wrote. I am probably missing out on some performance somewhere… but I am having no issues meeting some pretty strict performance requirements (DSP and real-time data visualization).