C++ Weekly - Ep 254 - C++23's signed / unsigned size_t Literals

Sdílet
Vložit
  • čas přidán 28. 05. 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...
    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 • 72

  • @LesleyLai
    @LesleyLai Před 3 lety +32

    This will fix one of the most annoying things in my day-to-day C++

  • @user-cy1rm5vb7i
    @user-cy1rm5vb7i Před 3 lety +11

    I'am still waiting for static type reflection. Hope it'll make it into the c++23

  • @ruadeil_zabelin
    @ruadeil_zabelin Před 3 lety +11

    I have custom literals in my codebase for exactly this. I called them _size_t and _ssize_t. I'm glad they're going to be a standard.

  • @VladykaVladykov
    @VladykaVladykov Před 3 lety +10

    Не успел перейти на С++20, уже 23

  • @6754bettkitty
    @6754bettkitty Před 3 lety

    I missed the "literals" part of the title when i saw the video notification. Now, it makes more sense!

  • @afborro
    @afborro Před 3 lety +5

    It should have been in c++17 already. What took so long :)

  • @vdvman1
    @vdvman1 Před 3 lety +1

    Hello Jason! I am a big fan of C++ Weekly, it has helped me learn so much more about C++ than I had ever hoped to know.
    I am just wondering if you ever covered C++20 modules? I can't seem to find a video when searching, and while I have had a look at what cppreference has about modules your videos often go into the small details that are easy to miss and give great examples.

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

      I haven't made any videos on modules yet because I'm still waiting on good compiler support.

    • @vdvman1
      @vdvman1 Před 3 lety

      @@cppweekly Ah, that makes sense 😅

  • @treyquattro
    @treyquattro Před 3 lety +4

    confused: size_t is already unsigned, why is there an unsigned qualifier? ptrdiff_t is accepted as the signed counterpart to size_t. The z and t format specifiers are already accepted in printf() since C++11.
    I suppose since size_t is implementation-defined, some perverse implementor could decide on a type that allows negative sizes?

    • @treyquattro
      @treyquattro Před 3 lety

      indeed. I think the fact that the committee have left both types to be implementation-defined means that they have to make explicit the programmer's intention within the context of their pointer and size definitions. The **convention** is that size_t is unsigned and ptrdiff_t is signed, but there is nothing to say you can't redefine them to any underlying types - or widths - you wish.

    • @user-cy1rm5vb7i
      @user-cy1rm5vb7i Před 3 lety

      sometimes it's useful to have a negative size, indicates an invalid size. This was used a lot in c with string sizes. If string is zero-terminated, then one could pass -1 as the string length. Not really a c++ thing to do, but still

    • @killerbee.13
      @killerbee.13 Před 3 lety

      @@treyquattro No, the standard does define that size_t is unsigned and ptrdiff_t is signed. (These requirements may not be spelled out specifically for the typedefs, but they are spelled out in the definitions of the sizeof and - operators.) The issue at hand is instead that the standard does *not* require them to be of the same width, which is brought up in the paper and visible onscreen in this video if you pause at 2:43. Signed sizes are indeed useful, and when they added span they also added ssize() functions for all the other containers, but that's a separate matter from the meanings of 0z and 0ut.

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

    What am I missing? Why would someone want to use auto on the lhs and then explicitly name the type on the rhs?

  • @nivo6379
    @nivo6379 Před 3 lety +5

    Very useful. Allows using `auto` everywhere like `let` in Rust.

    • @samu6982
      @samu6982 Před 3 lety +1

      It's already almost like that, but that's not a very good idea, C++ is a statically typed language using 'auto' everywhere just hides useful information

    • @nivo6379
      @nivo6379 Před 3 lety

      @@samu6982 Rust and many other languages are statically typed too. C++ is no different. You don't need to write something that the compiler already knows.

  • @timangus
    @timangus Před 3 lety +1

    Not the same, but related: working with Qt and the standard library in the same project (so basically every Qt project), with any sort of sensible set of warnings enabled your code is covered in static_casts to and from int and size_t :(. (That are no doubt hiding lots of subtle bugs when containers get large.)

    • @masondeross
      @masondeross Před 3 lety +1

      Yeah, Qt is kind of infuriating with haphazard int's where they meant size_t's. If you want to compile your code with C++17 or later and have all warnings on, it helps to surround every Qt header include with `#pragma warning(push, 0)` ... `#pragma warning(pop)` or your warning spam will be intense even with Qt6. Unless it's part of your job to verify the library is working correctly, which I wouldn't envy.

  • @petermuller608
    @petermuller608 Před 3 lety +3

    Great content! However the animations between cuts are a bit wordarty ;)

  • @motbus3
    @motbus3 Před 3 lety +3

    c++ is getting crazy

  • @vorpal22
    @vorpal22 Před 3 lety

    FINALLY. I am so tired of having to use size_t instead of auto in variable declarations when working with STL collections and manual algorithms.

  • @jimvonmoon
    @jimvonmoon Před 3 lety +8

    Is there any advantage of using `static_cast(32)` over `std::size_t(32)`?

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

      Yes, and no. I would use `std::size_t{32}` instead. `std::size_t(32)` is actually a c-style cast and will do any conversion that's possible, and this could be bad if you made a typo. The braced-init version should prevent (at compile time) any lossy conversion.

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

      @@cppweekly What? No, it's not a C-style cast. A C-style cast would be (std::size_t)32. std::size_t(32) is a C++ constructor call, a C compiler will reject size_t(32).

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

      @@tjthill For fundamental types it is a C-cast. For classes it is not always a constructor call - might be a conversion.

  • @praveerroshan8376
    @praveerroshan8376 Před 3 lety +1

    could you please provide the url of the site which you referred to @31 secs ?

  • @hkmix
    @hkmix Před 3 lety +1

    It seems like given the current revision the EWG accepted z/zu but rejected t/tu, so we're getting one but not the other? Rather curious choice since I think there will definitely be confusion as to why z != ptrdiff_t, even if the paper does justify why that is the case.

    • @treyquattro
      @treyquattro Před 3 lety

      both size_t and ptrdiff_t are implementation-defined but are anticipated to be unsigned and signed respectively. I would expect z == tu if you somehow needed to then have an unsigned ptrdiff_t. The fact that they are implementation-defined complicates the situation and I suppose means they have to include zu and tu to make it explicit.

    • @hkmix
      @hkmix Před 3 lety +1

      @@treyquattro I agree, and maybe I wasn't totally clear, but my confusion was more on the side of why one was accepted and not the other -- seems like it'll just lead to more confusion that way and a longer adaptation time to using these.
      In practice I think maybe I would just use z/uz until we end up with a definitive type for ptrdiff_t given they're equivalent on most systems, but it's a bit annoying that we won't have both (assuming my read of the proposal is right).

  • @pendergastj
    @pendergastj Před 3 lety +1

    Jason, what's your favorite C++ feature?

    • @vorpal22
      @vorpal22 Před 3 lety +4

      LOL isn't is obvious? Lambdas.

  • @maartenofbelgium
    @maartenofbelgium Před 3 lety

    You passed `-std=c++2a` to the compiler. Do the compilers accept `-std=c++2b` already?

    • @masondeross
      @masondeross Před 3 lety +1

      Hm, not sure on that. I like how for msvc it's just `c++latest` to use whatever is the newest, even if you don't know newest postfix.

  • @adamshield5029
    @adamshield5029 Před 3 lety

    Nice video. What would be the use case of an unsigned size_t do you think?
    Edit: oops I meant signed size_t

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

      I mean. A size of a type can't be negative. Neither can the number of elements in a container/array/buffer. I know some committee members are like "everything should be signed", but I disagree.

    • @adamshield5029
      @adamshield5029 Před 3 lety

      @@lincolnsand5127 oops I meant signed size_t. For the reasons you mentioned, I’m trying to imagine when it could ever be used ever. Like is it purely a theoretical type?

    • @lincolnsand5127
      @lincolnsand5127 Před 3 lety

      @@adamshield5029 You can use the negative numbers to encode errors

    • @killerbee.13
      @killerbee.13 Před 3 lety +2

      @@adamshield5029 if (ssize(range1) - ssize(range2) < 0) is a slightly contrived example of where signed sizes makes a difference, but something slightly more elaborated could easily come up in normal code.
      For instance, if you write a loop which does something with "extra" elements at the end of one range, using the difference of their sizes for the loop condition variable with a < comparison would make sense, and with signed sizes, it would not run the loop at all if the difference is negative, but with unsigned sizes, it would run the loop an absurdly large number of times and very probably cause UB.
      When you subtract two sizes now, if you haven't already made sure to subtract small from large, the result is meaningless (Well, you could compare it with numeric_limits::max()/2 to get the same effect as seeing if it's negative, but that is hideous.) But with a signed size, the result behaves exactly as you would expect.

  • @DamianReloaded
    @DamianReloaded Před 3 lety

    size_t can be kinda evil if one's not careful cross compiling between 32/64 bits. Always storing the result of .size() into a uint64_t is the simplest way to be sure I won't mess up. Also what's wrong with: auto val = (uint64_t)myvec.size(). I only use uint[size]_t s to store integers.

    • @cppweekly
      @cppweekly  Před 3 lety

      This is the opposite of what I would recommend. If you always force it into a 64bit integer you're going to cause other headaches and performance pessimizations on 32bit platforms. If you use size_t and/or auto consistently you won't have any risk of that.

    • @DamianReloaded
      @DamianReloaded Před 3 lety

      @@cppweekly I agree. Still if you developed something relatively big for 32bits, and sometime later you ported it to 64bits, and the app crashed and you couldn't find where the bug is, check if by any chance you're assigning a size_t to a 32bits varible. I ran exactly into this and I don't remember if it was an explicit cast and the compiler didin't warn me or if I simply ignored the warning but after debugging it I got a bitter taste in my mouth that it could have been much harder to find in other circumstances..

  • @stertingen
    @stertingen Před 3 lety

    Why is that considered a 'core language feature'? For me it looks like some user-defined literals which can be provided by the STL.

    • @LEpigeon888
      @LEpigeon888 Před 3 lety +1

      Because it's not an user-defined literals and it won't be defined in the STL. You will be able to use it without including any file or using any namespace.

  • @jbar7742
    @jbar7742 Před 3 lety +1

    is size_t becoming a language feature then? i.e. a keyword instead of a typedef

    • @user-cy1rm5vb7i
      @user-cy1rm5vb7i Před 3 lety

      someone should just make a proposal already. And some compilers already have that feature, like msvc

    • @killerbee.13
      @killerbee.13 Před 3 lety

      No, the core language way to spell it will remain some variation on `decltype(sizeof(int))` (and std::ptrdiff_t is something like `decltype(static_cast(nullptr) - static_cast(nullptr))`, for comparison). There's no reason to make the typedefs keywords.

    • @jbar7742
      @jbar7742 Před 3 lety +1

      @@killerbee.13 well we wouldn't need to qualify them using the std namespace anymore .. 5 characters less

    • @killerbee.13
      @killerbee.13 Před 3 lety

      @@jbar7742 I mean, you don't really have to now on most implementations, because they're almost always declared in C headers in the root namespace. But even besides that, you can `using std::size_t;` if you want.

    • @jbar7742
      @jbar7742 Před 3 lety

      @@killerbee.13 well there is no guarantee that they do so, and and a global using declaration is meh

  • @bennitec5280
    @bennitec5280 Před 3 lety

    finally

  • @marco21274
    @marco21274 Před 3 lety

    What about that all this types are aliases. It gets really nasty if they map to different integer types on different platforms. Like this long long vs long problem. Every time I explain it to novices they ask me way the int32_t is an alias to int not the other way around. Maybe it was a smart idea in the seventies but today it is a bug source. 😏 With modules they should provide a sane integer behavior which you can opt in per file. 😉

  • @maksymiliank5135
    @maksymiliank5135 Před 3 lety +1

    Why 'z' though? Why not just use 's' instead?

    • @gbnam8
      @gbnam8 Před 3 lety

      it's already the suffix for shorts

    • @user-cy1rm5vb7i
      @user-cy1rm5vb7i Před 3 lety +1

      @gbnam8 there're no suffixes for short types. But a lot of suffixes have migrated from printf identifier specs. And %s is a string, not a size_t

    • @Arganoid
      @Arganoid Před 3 lety +1

      s is string

    • @killerbee.13
      @killerbee.13 Před 3 lety +1

      @@Arganoid Also seconds

    • @maksymiliank5135
      @maksymiliank5135 Před 3 lety +1

      @@Arganoid Yes, but it could be overloaded for unsigned long long type.

  • @user-cy1rm5vb7i
    @user-cy1rm5vb7i Před 3 lety +1

    why is everyone so afraid of c-casts? Unless u cast pointer/reference values to another pointer/reference type then it's 100% safe and much more readable. Ofc 32uz is shorter even comparing to (size_t)32, but still.

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

      c-style casts can convert almost anything to almost anything else. They are worse than `reinterpret_cast`. If you want to go down this road, then you should use the braced-init style instead `std::size_t{32}` to avoid potential accidental conversions.

  • @romeklomek5646
    @romeklomek5646 Před 2 lety

    C++ is getting more and more ridiculous. I loved that language, and now I'm beginning to at the same time hate it and find it silly. It literally is like putting lipstick on a pig. Why uz? In what way does that indicate the type? Couldn't they (the "geniuses" from committee) come up with something approaching normal? Like u32, us, u64 etc? Really, uz, what on hell does that suggests?

    • @dat_21
      @dat_21 Před 11 měsíci

      You can't love c++. You tolerate just enough it to get things done.

  • @Voy2378
    @Voy2378 Před 3 lety +1

    On a related note WG21 clowns did not add ssize member methods to containers... only std::ssize, typical C++ nonsense

  • @myhardware1420
    @myhardware1420 Před 3 lety

    i am a fan of AAA, but auto index = 0uz is not very good readable.
    u read it and think "wtf was that?" auto delay = 1us is understandable.

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

    How about just not use "auto".....

  • @solarcrystal5494
    @solarcrystal5494 Před 3 lety +5

    2 letters for the more used unsigned size_t type, 1 letter for the less used signed size_t type. this is garbage

    • @killerbee.13
      @killerbee.13 Před 3 lety +3

      Every unsigned literal has a u in it, though. Having z behave differently would be weird and inconsistent (especially as there is no literal suffix for signed)