C++ Weekly - Ep 287 - Understanding `auto`

Поділитися
Вставка
  • Опубліковано 2 лип 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...
    Upcoming Workshop: Applied constexpr: The Power of Compile-Time Resources, C++ Under The Sea, October 10, 2024
    ► cppunderthesea.nl/workshops/
    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/...
  • Наука та технологія

КОМЕНТАРІ • 99

  • @fixpontt
    @fixpontt 2 роки тому +25

    this was the first topic i read from Scott Meyers' book about C++11

    • @superscatboy
      @superscatboy 2 роки тому

      His explanation is excellent, and necessarily thorough.

  • @grahampitt8882
    @grahampitt8882 2 роки тому +7

    In 1984 Bjarne had a working implementation of auto in c++, but that keyword was already being used for something else.
    Should he have:
    A) Drop that feature for 17 years; or
    B) Pick a different keyword, like 'var'.
    Obviously the answer chosen was A. 🤔

  • @TomHultonHarrop
    @TomHultonHarrop 2 роки тому +9

    Great video! One extra thing that might be worth calling out in a future episode is the difference between 'const auto const_pointer_to_integer = &some_integer;' vs 'const auto* pointer_to_const_integer = &some_integer;' - The first will be a constant pointer and not a pointer to a constant value which I think does catch people out. If you want both you can write 'const auto* const const_pointer_to_const_int = &some_integer;'. I also think it's interesting as an analogy to think of a reference as like a portal to a value (an intangible thing you can't really touch (copy)) and a pointer as a picture you can hold and copy and pass around but with a button to teleport you to the picture (dereference :P). It's not perfect, but I thinks help distinguish how the language treats pointers and references. I think added confusion also comes from people saying how references and pointers are technically 'the same' under the hood which I don't think helps with understanding (definitely for me anyway).

    • @cppweekly
      @cppweekly  2 роки тому +14

      An entire episode on template pattern matching might be called for, and relate that back to auto along the way

    • @z08840
      @z08840 2 роки тому +1

      @@cppweekly decltype(auto) i_ref = (i); // deduce reference!!!

  • @popvic7666
    @popvic7666 11 місяців тому

    Great video

  • @ltstaffel5323
    @ltstaffel5323 2 роки тому +10

    Don't know when you switched, but dark mode compiler explorer is a +1 from me :)

  • @metal571
    @metal571 2 роки тому +1

    Effective Modern C++ Weekly

  • @JanSordid
    @JanSordid 2 роки тому +6

    To me, working in a huge codebase where you encounter unknown parts of code multiple times each day, having a 'very rarely auto' policy is a bliss.
    When the type of the variable is stated then I do not have to look at the declaration of the function that initialized it. It makes reading code so much easier.
    I definitely like auto for for-loops or in generic contexts, but this use case does not make up too much of most involved developers lives.

  • @neozoan
    @neozoan 2 роки тому +3

    Whoo, boy. Time to find out how much I don't actually understand about auto.

  • @willofirony
    @willofirony 2 роки тому +11

    And there was me thinking my ancient brain was confused by auto, when all the time it was that auto IS confusing. I would be interested in knowing what, exactly, was the intention of the creator(s) of auto. Personally, I don't find any problems in not using auto, particularly when it comes to my code's readability. I look forward to the next episode to find out where I have been wrong in that belief.

    • @michalmrena
      @michalmrena 2 роки тому +5

      If nothing else it is useful when you want to avoid long templated types e.g. iterators:
      std::vector xs = {1, 2, 3};
      std::vector::iterator it1 = std::begin(xs);
      // vs
      auto it2 = std::begin(xs);
      It is also neccessary when you want to store a lambda in a variable:
      auto id = [](auto x){ return x; };
      I personally use Always auto style and I really like it, I've never had a problem with types. But I am only working on small personal projects.

    • @willofirony
      @willofirony 2 роки тому +5

      @@michalmrena Thanks for that, Michal. I can see the value of auto in those examples. You may very well have made a convert of me. I hope the compilers look kindly on you in reward.

    • @benjaminnavarro865
      @benjaminnavarro865 2 роки тому +5

      @@willofirony It's also nice to avoid having the type written twice in some cases, e.g. auto x = std::get(tuple);. You know you'll get an int from the RHS so it doesn't add any information to specify it on the LHS. Not using auto is this case is more verbose, esp. with longer types, and can trigger some implicit conversions if both type are not the same (it's easy to change either the LHS or RHS without changing the other). Also in some weird cases you must use auto like if an API returns a private type. This is because you're not allowed to name it, but you're free to use it.

  • @GeraldSquelart
    @GeraldSquelart 2 роки тому +13

    around 7:42 "pointer ... is part of the type [of p]", that's why I really prefer the declaration style `int* p = ...;` 😉

    • @masondeross
      @masondeross 2 роки тому

      Agree aside from the assignment initialization. Always Bracket... C..... ugh I don't want to abuse the word construction even though it would fit the ABC thing I'm trying to make... I just like brackets, okay. Except sometimes when I want to make it clear a function (potentially in a third party library, and/or potentially expensive to call) is being called in the initialization of a complicated thing where the () could be buried. I love putting immediately called lambda's with return values into {} initialized variables, though. The function call initialization assignment thing is kind of a legacy habit I use less and less. I can always throw the function call in a lambda, after all.

    • @jhbonarius
      @jhbonarius 2 роки тому +1

      I also do that, but it goes wrong when you declare multiple variables. I.e. "int* a, b;" a will be int*, b wil be int.

    • @obinator9065
      @obinator9065 2 роки тому

      @@jhbonarius i would avoid assigning such trivial names to pointers, they already attract loads of bugs and make the program unreadable. And if you pick readable names your line will also be clumsy. That’s why I prefer declaring variables separately and only when they’re about to be used in the next code line. This provides a clearer program structure to me + much needed type information.
      If I want to find all the int pointers in my project I’d only have to search for ‘int*’.

    • @jhbonarius
      @jhbonarius 2 роки тому +2

      @@obinator9065 what? It's not about the naming. I'm just making an example. Slideware. It's about the pointer type not being used for both variables this way.
      Yes, of course you should declare variables on separate lines and even initialize them on declaration.

    • @GeraldSquelart
      @GeraldSquelart 2 роки тому +1

      @@jhbonarius That's why another favorite guideline is "never declare more than one var in a statement". 😁 (Only exception being in `for` multiple inits, but that's very rare, and I usually try to take them out anyway.)

  • @Avianable
    @Avianable 2 роки тому +2

    at 8:28 it's not an explicit dereference. That would be putting a * in front of a pointer type. You were taking the address of an integer.

  • @KennyMinigun
    @KennyMinigun 2 роки тому

    One more thing about auto, const and pointers:
    int* p = nullptr;
    const auto constPtr = p; // a const pointer to a mutable object
    const auto *ptrToConst = p; // a mutable pointer to a const object

  • @xkazinx
    @xkazinx 2 роки тому +8

    There's an interesting thing about const pointers declared with auto that is not being mentioned here:
    const auto* ptr = new int(1); // This results into const int* - Can't call const attributes but can change pointing value
    const auto ptr = new int(1); // This results into int* const ptr - Can call const attributes but can't change pointing value
    const auto* const ptr = new int(1); // Can't call const attributes nor change pointing value

    • @kaosce
      @kaosce 2 роки тому

      I don't think it is related to auto but just pointers

    • @jhbonarius
      @jhbonarius 2 роки тому

      Well, raw pointers are not really necessary in modern C++ anyhow. Use RAII, use std::unique_ptr.

    • @xkazinx
      @xkazinx 2 роки тому

      @@jhbonarius I guess they are if you're using a C library or a C++ library that still uses raw pointers for some reason, like in my case. Also, objects with non-trivial destructors can't be passed to registers, which is the case for unique_ptr, and not for raw pointers.

    • @jhbonarius
      @jhbonarius 2 роки тому

      @@xkazinx? When would you use "new int(1)" for a register?

    • @xkazinx
      @xkazinx 2 роки тому

      @@jhbonarius I don't mean it for this specific example of an int, but for other custom objects that a unique_ptr can hold. I would need to investigate and elavorate a relevant example for this to prove it right thought: I have the vague thought that, due to this, in an intensive-called function or loop, a raw pointer could be faster than a pointer holded by unique_ptr, but I could be wrong.

  • @badasahog
    @badasahog 2 роки тому +1

    I've seen decltype(auto) before but I still don't understand what it does. If you could do an episode about it that would be nice

  • @abdulrahmanhamdi1782
    @abdulrahmanhamdi1782 4 місяці тому

    I have some thoughts, the auto shall be accompained by modifiers const and references to get the exact deduction, the reason why it failed to compile the assignment of the address of const int i to pointer p because the address itself is unique and can't be copied ..so i can't manipulate memory location represented by const i. Auto take a copy or deduce the type of the return value and need both & and const to be accompanied with it.

  • @benjaminshinar9509
    @benjaminshinar9509 2 роки тому +1

    I've been reading the 'modern effective c++' book lately, was there any changes addition for auto and {} since c++17?
    looking forward to next week!

    • @cppweekly
      @cppweekly  2 роки тому

      No, as far as I know nothing has changed since C++17

  • @josemicorrea4021
    @josemicorrea4021 2 роки тому

    Can anybody post compiler options as we can barely see it at the right top of Compiler Explorer? Thanks in advance.

  • @kyoai
    @kyoai 2 роки тому +1

    I usually avoid using auto because while skimming through code I like to have types visible, so all points it is 100% clear what type each variable is, without having to hover my mouse over the variable/returning function. Auto also makes it harder to find type usages when doing a plain text search for types. The only times I really like using auto is for having lambda variables, for template code and for using auto as a quick'n'dirty placeholder for item types in a ranged for loop. However, once the loop is implemented I usually replace the auto with the actual type.

    • @vorrnth8734
      @vorrnth8734 2 роки тому

      Interesting, I usually always use auto because most of the time i am not interested in the actual type.

  • @alextrotta796
    @alextrotta796 2 роки тому +1

    I would like to see more with decltype(auto). I've tried to understand it, but there's not a whole lot of good material, and to me it doesn't have any intuitive meaning, much less a useful one.

  • @LogicEu
    @LogicEu 2 роки тому +9

    I've always thought that the auto keyword is more confusing than helping. I know there are case where auto is extremely helpful, but imagine I want to understand a codebase full of autos, It's gonna be impossible for me to fully grasp what the types are, if they are refs, pointers, consts, etc. My take is; use auto when it's helpful, not because of laziness. I always want to know that an int is an int, not guess or deep dive into the function call tree to know what I'm dealing with.

    • @LEpigeon888
      @LEpigeon888 2 роки тому +3

      > not guess or deep dive into the function call tree to know what I'm dealing with.
      Just use an IDE, it will save you a lot of time. Then you will just need to hover the variable with your cursor (or read the doc of your IDE if it's not how it works).

    • @LogicEu
      @LogicEu 2 роки тому +7

      @@LEpigeon888 Yes! I know! But my point is having a reason to use the auto keyword. Let's say we have something like auto i = 42. Who benefits from this variable being auto?? What's the point of it??? It's much more clear what the purpose of the variable is and what you can do with it when the type is explicit. This isn't python after all...

    • @LEpigeon888
      @LEpigeon888 2 роки тому +1

      @@LogicEu Yes sometimes it's not necessary you're right.

    • @err6910
      @err6910 2 роки тому +9

      Well in my opinion, if you need an IDE to read the code by hovering over the variables, that means the code is not readable.

    • @err6910
      @err6910 2 роки тому +2

      @Eugenio Arteaga - In addition, I would say that if you need to call a function, which we do quite often in real code bases, you have to name the type of the parameters of the function anyway (well except on tiny projects where you could write every function as templates, but well...)... So better to declare the variables with the right type so that it's obvious that the types match. auto in template code definitively makes sense, and also when using very localized variables with complex types like iterator, but we have to be very careful with proxies or expression templates, this might not do what we expect.

  • @jhbonarius
    @jhbonarius 2 роки тому +9

    I find it hard to understand why people have such difficulty with it. But maybe that's just my neurodivergent mind.
    My team lead hates it and "fixes" every piece of code he finds it in. Maybe something like "I can't see the type, so I get confused" or so. But most times you don't care what the type is. And if you care, you would rather need a concept than a specific type.

    • @treyquattro
      @treyquattro 2 роки тому +1

      I would suggest it's your team lead who's the one that is "neurodivergent"

    • @cppweekly
      @cppweekly  2 роки тому +4

      Wait for next week's episode which is probably the one you want to share with the team.

    • @jhbonarius
      @jhbonarius 2 роки тому

      @@treyquattro yes he is. It's great to have multiple neurodivergent people in one team. Not.🙄

  • @Qazqi
    @Qazqi 2 роки тому +1

    Unfortunately, there's one small difference between auto and template type deduction (auto allows "deducing the type of" {...}, which doesn't have a type because it isn't an expression). It's a pretty insignificant difference, but a bit frustrating that it removes the otherwise perfect consistency. Though I haven't checked yet, a C++20 `void foo(auto);` might make it slightly more inconsistent in that regard because this auto would probably use the template rules, not the auto ones. (That said, I would still agree with the decision because "auto-based" (placeholder) parameters definitely should just be syntax sugar for a template.)

    • @davidkatz1017
      @davidkatz1017 2 роки тому

      I believe auto in function parameter acts exactly like shorthand for template declaration, so you can't pass it just braces with no type.
      I personally really like it. Makes writing generic functions so much less verbose.

  • @judahmatende3769
    @judahmatende3769 2 роки тому +1

    Video is too dark.
    Thank you for the good work! Keep it up!

    • @JanSordid
      @JanSordid 2 роки тому

      I also like to code in a dark mode IDE, but watching videos of dark mode IDEs is detrimental to me as well. I watch videos like this occasionally on my smartphone where dark mode does hinder readability

    • @cppweekly
      @cppweekly  2 роки тому

      Hmm, I'm not sure what to do here. I mostly try to avoid drastic changes between light and dark, but most people seem to prefer the dark mode...

  • @Omnifarious0
    @Omnifarious0 2 роки тому +4

    I don't like auto sometimes because it hides type information. This isn't a problem most of the time. Mostly the type is obvious from context. But that's not always the case.
    Another place where I think auto is contraindicated is when the code following depends on the variable being a specific type. I would rather the type error than the weird errors that occur when a possibly similar type is used in the wrong way.

    • @klimovNS
      @klimovNS 2 роки тому +4

      +1
      Especially if you outside IDE, overuse of auto make code extremely hard to read. For myself I made this rules.
      I always use explicit types unless
      1. It's just a pain to write it (iterators)
      2. It's already been written (e.g. in std::make_shared)
      3. I do not use it, just forwarding to another function

    • @Omnifarious0
      @Omnifarious0 2 роки тому

      @@klimovNS - I'm also willing to use it when the type is semi-obvious in context. Like the result of .size, for example.

  • @DamianReloaded
    @DamianReloaded 2 роки тому +3

    I love auto and I try to use it where it makes my code better. auto is more a casual lover than a marriage imc ^_^

  • @z08840
    @z08840 2 роки тому

    int i = 5;
    decltype(auto) i_ref = (i); // deduce reference!!!
    i_ref = 13; // now i == 13

  • @edwardboggis-rolfe
    @edwardboggis-rolfe 2 роки тому +1

    The danger I have with auto, is that it does a copy accidentally when one did not mean to do a copy, when you meant it to be a reference, and there is no way to say that you want want the auto to be not be a pointer. This I find a serious problem when reviewing other people's code as it is very easy to miss. I would like have something like an auto^ to indicate an explicit non pointer value type so that we do not need to have naked autos in code reviews.

    • @NoNameAtAll2
      @NoNameAtAll2 2 роки тому

      Are you suggesting "auto^ a = (int*)p" to magically transform pointer into an int? How? By hidden dereference?
      What about invalid pointers?

    • @edwardboggis-rolfe
      @edwardboggis-rolfe 2 роки тому

      @@NoNameAtAll2 it will give a compiler warning, the point is there is no coercion. It will force people to declare that this is a deliberate copy and not an implicit one. In your example you would have to use auto*

    • @edwardboggis-rolfe
      @edwardboggis-rolfe 2 роки тому

      Or use “auto^ a = *(int*)p” if you really want to copy a dereferanced pointer

    • @cppweekly
      @cppweekly  2 роки тому +1

      I'm going to do an episode about constraining auto, which I think would reduce some of your concerns.

  • @simonfarre4907
    @simonfarre4907 2 роки тому +5

    C++ is so weird when you think about it. "It will deduce pointer because that is a type" yet a reference isn't

    • @Artaxerxes.
      @Artaxerxes. 2 роки тому +5

      thats because a pointer actually occupies memory. 8 bytes iirc. But a reference is just that. A reference. Scott meyers gives a nice explanation about type deduction. It makes sense to me that a reference isn't deduced. Because it doesnt store anything at all. A pointer does store the address

    • @rudolflovrencic
      @rudolflovrencic 2 роки тому +1

      ye, it's good to think of a reference as just another name (an alias) for a variable. Pointer, on the other hand, is a variable (like any other) that stores an address of another variable. Since aliases are special (you get the same syntax as if you are accessing the variable that is referenced directly, while with pointers you use &,*,->) , the language must provide special rules for them.

    • @simonfarre4907
      @simonfarre4907 2 роки тому +1

      @@Artaxerxes. yes, one does have to do a bit of mental gymnastics to truly understand c++ references - however, most other languages has gotten this down in far superior ways. C++ botched the terminology and Meyers all though well intentioned explanation that makes sense, is still mental gymnastics. You can have member variables that are references, arguments to a function that are references, and these behave much like pointers - and they take up space for instance. C++ references does essentially suffer from what could be call an abstraction leak.

    • @simonfarre4907
      @simonfarre4907 2 роки тому

      @@rudolflovrencic my response to other comment also works as a response to you.

    • @treyquattro
      @treyquattro 2 роки тому +2

      @@Artaxerxes. a reference occupies memory too. Under the covers it's just a pointer, but one that can only be initialized and not reassigned. (The compiler can optimize away storage of a reference if it's a simple use case, but it will reserve space for the reference if needed). A reference is an address.

  • @OperationDarkside
    @OperationDarkside 2 роки тому +2

    Again, I find myself enjoying these videos more on a higher speed

  • @teaching-related-videos3339
    @teaching-related-videos3339 2 роки тому

    I don't think this is right. If I do auto v=vec.back(), from std::vector and then change the value of v, the vector itself changes.

    • @codyheiner3636
      @codyheiner3636 2 роки тому +4

      std::vector is not an array of bools. Change it to int or anything else and you will see the behaviour as he described.
      Read the second bullet point here for more details: en.cppreference.com/w/cpp/container/vector_bool

    • @teaching-related-videos3339
      @teaching-related-videos3339 2 роки тому

      @@codyheiner3636 you're right. So it's probably sending around a pointer to the original vector object + index. Possibly an argument against auto.

    • @killerbee.13
      @killerbee.13 2 роки тому +1

      @@teaching-related-videos3339 personally I consider it more of an argument against proxy types, though I know that sometimes they're a necessary evil (I've even written a couple myself). However, proxy types can do some to alleviate this, for instance having rvalue-qualified member functions to cause errors when they're saved and used as variables. (Though that approach has some drawbacks of its own.)

  • @organichand-pickedfree-ran1463
    @organichand-pickedfree-ran1463 2 роки тому +4

    What makes these things hard to remember (and therefore developers trust it less), is that it's far from obvious how auto and template type deduction works.
    There a large number of rules.
    And like here it's presented without much explanation, which makes these rules harder to remember.
    I'm not even sure why auto needs to follow the same rules template type deduction does, or why writing "decltype" around auto would change the semantics of it.
    In case of the pointer this is not quite right.
    A pointer to const int seems to be copied the same way a normal const int would be copied.
    int a = 1;
    const int b = 1;
    auto* i = &b;
    i = &a;
    works.
    And I guess the "why" is, if "if you make a copy, you might as well make it non-const". Debatable choice.
    Most developers don't want to care about the details, because they are trying to achieve some domain goal, and not deep-dive into C++ semantics.
    Plus for codereview you want to write code that everyone understands.
    Not using auto works quite well in most contexts.
    Plus for readability reasons it also often makes sense to avoid auto.

  • @Sebanisu
    @Sebanisu 2 роки тому +1

    I don't always trust auto*. Some functions return a pointer on gcc, and an iterator on msvc. So if I do auto* it won't compile on msvc. I can see auto* making sense if you are creating the pointer.

  • @erichlf
    @erichlf 2 роки тому +1

    Don't trust auto + Eigen, you will almost certainly not get what is expected.

  • @toRatnesh
    @toRatnesh 2 роки тому

    How does use of auto impacts performance?
    Anyone please share 🔗 any good blog or video tutorial

    • @93davve93
      @93davve93 2 роки тому +5

      I would’nt think that there is any performance difference since auto is a compile time abstraction. Please correct me if i’m wrong.

    • @cppweekly
      @cppweekly  2 роки тому +5

      Next week will discuss performance + auto

    • @93davve93
      @93davve93 2 роки тому

      Unless there is an implicit conversion with performance side effects in the case of not using auto…?

  • @aryansabetnejad3886
    @aryansabetnejad3886 2 роки тому

    I really don't understand auto.