Пікірлер
@SamWhitlock
@SamWhitlock 9 күн бұрын
I hadn't know about this part of C++ Insights. Neat! Are there any other areas in C++ where this "anti-dangle" stuff is performed? If you did `get().items()` outside of this context, you'd still get a dangling ref, e.g. `auto &items = get().items(); auto b = items.begin(); // kaboom here`. I understand practically why this behavior is special-cased for the range for loop, but is this the only context in which it is done?
@ask43242flight
@ask43242flight Ай бұрын
How do I use a third-party library (i.e. simdjson library) on c++ insights website? Thank you
@sanjaygatne1424
@sanjaygatne1424 Ай бұрын
फाॅन्ट आकाराने लहान आहे. वाचायला त्रास होतो.
@almondengine
@almondengine Ай бұрын
I didn't know that trick or tool, now I do thank you!
@EddingDefault
@EddingDefault 2 ай бұрын
Pedagogically speaking, I think that the analogy in the beginning can be clarified by saying that references and pointers are similar because they are both mechanisms of indirection. They are different, because the language doesn't treat them as assignable values. This separation of dimensions of likeness and difference maps onto the performance implications: indirection requires references to be represented as addresses in CPU in all but the most contrived usage scenario, so just like for pointers the indirection cost is there. But transient references don't need their own storage and can indeed ever only be in registers, which differs from pointers.
@iuiui-iuiui
@iuiui-iuiui 2 ай бұрын
If you claim performance, show a benchmark! I'd say user strings are not long enough to note any significant difference
@iuiui-iuiui
@iuiui-iuiui 2 ай бұрын
Am I the only one who is mesmerised by the std::basic_format_string template arguments mimicking the other arguments to std::println? What kind of sorcery is that?
@AlfredoCorrea
@AlfredoCorrea 2 ай бұрын
I think this is because std::println deduces the second and third argument and imposes these template arguments into its first argument. Cppinsights shows this argument type of the called function because there is a conversion involved.
@AlfredoCorrea
@AlfredoCorrea 2 ай бұрын
I guess this can bring some clarity in which cases the program will do (or not do) life-time extension with `auto const&` and `auto&&`. Very nice.
@sanjaygatne1424
@sanjaygatne1424 2 ай бұрын
सी ++ इनसाईट बहोत ही उपयुक्त है.
@McDonaldIbekwe
@McDonaldIbekwe 2 ай бұрын
Nice video with very clear explanation.
@MarcosCpp
@MarcosCpp 3 ай бұрын
I liked this video, quick and straight to the point
@KalkiCharcha-hd5un
@KalkiCharcha-hd5un 3 ай бұрын
Your vids are unreadable on mobile screen size I wish it had bigger fonts.
@iuiui-iuiui
@iuiui-iuiui 2 ай бұрын
Try pinch to zoom👌
@xorbe2
@xorbe2 3 ай бұрын
Need to differentiate reference as a local variable vs an object member variable. Locally it can just be a name alias effectively. In an object, it's basically a pointer and you can actually get hacky and change what the reference references.
@gehirndoper
@gehirndoper 3 ай бұрын
Interesting, but I think in most cases this does not make a difference: If the pointer is only used locally, the compiler should optimise storing it away if possible. Conversely if you have a class which stores a reference to something, this would take the same space as storing a pointer.
@imranjavaid71
@imranjavaid71 3 ай бұрын
For your first point of compiler optimizing it away, I don't think that is true. You can test that be adding "-O3" to the compiler-explorer code in the description. Second point is correct. The reference will take space in a class.
@gehirndoper
@gehirndoper 3 ай бұрын
@@imranjavaid71 You are diplaying the address of the pointer, so this is not a relevant example.
@tomkirbygreen
@tomkirbygreen 3 ай бұрын
Great video sir. I think you might want to consider changing ‘no’ to ‘not’ in the title.
@TheMR-777
@TheMR-777 3 ай бұрын
That's actually an accented way of saying it :)
@andreas_fertig
@andreas_fertig 3 ай бұрын
Thanks! I think its to late to change.
@valentinsiltsenko
@valentinsiltsenko 3 ай бұрын
Thank you for the great explanation!
@Luckygangff
@Luckygangff 3 ай бұрын
hi sir i wrote a generic code for stl containers but cpp insights it is not compiling can you please help me to solve it #include<iostream> #include <list> #include<vector> template<typename T,template<typename> class X> void print(X<T> &container){ for(auto &i: container) { std::cout<<i<<" , "; } std::cout<<" "; } int main(){ std::vector<int> a{1,2,3,4,5,6}; std::list<double> b{1.5,2.5,3.5,4.5,5.5,6.5}; print(a); print(b); return 0; }
@garyp.7501
@garyp.7501 4 ай бұрын
That is a good tip if you want to make your assignments always use a reference to the object.
@rafalmichalski4893
@rafalmichalski4893 4 ай бұрын
Why do we need this cast as const & binds to everything - even to non-const && (which is returned from std::move) ?
@AlfredoCorrea
@AlfredoCorrea 4 ай бұрын
Why CppInsights puts a static_cast to const Apple&& and not to const Apple&, which is the argument of the copy constructor? Great video!
@mlavik1
@mlavik1 4 ай бұрын
Great video! Is it possible to get a warning for this somehow? (though Clang Tidy or something). If I do std::move explicitly I wouldn't want it to be copied, at least not in non-template code. These kind of issues can be really had to spot :'D
@sebastienlevy8127
@sebastienlevy8127 4 ай бұрын
Excellent example for if consteval, outlining with a practical use case the difference with std::is_constant_evaluated. It builds a clear bridge between the pure compile-time world and the hybrid compile-time/run-time world represented byt constexpr context. Great video, keep up the good work!
@tomkirbygreen
@tomkirbygreen 5 ай бұрын
Awesome video. I don’t know if you have any interest or ability to edit the presentation at this point but there’s a missing ‘h’ in ‘tings’.
@andreas_fertig
@andreas_fertig 4 ай бұрын
Thanks! Unfortunately, I can't edit/update the already published video :-)
@adeelahmad9875
@adeelahmad9875 5 ай бұрын
Nice !!
@panjak323
@panjak323 6 ай бұрын
So why isn't noexcept the default?
@andreas_fertig
@andreas_fertig 6 ай бұрын
Well, because it was introduced a long time after C++98. In addition it is a save default. Once you start throwing exceptions which pass functions which are noexcept default things get hard.
@garyp.7501
@garyp.7501 6 ай бұрын
Of course now I want to use a Macro to fill in the boiler plate code. #define LogMyError(x) LogError(std::operator""sv(x, 11UL), std::source_location::current(__buildin_source_location())) LogMyError("Just a test);
@andreas_fertig
@andreas_fertig 6 ай бұрын
Sarcasm? I don't get why you would want to use a macro and why use __builtin_source_location() in ::current. The compiler does that for you already.
@garyp.7501
@garyp.7501 6 ай бұрын
@@andreas_fertig Then I was confused at 4:50 or so where you used it. The define is to avoid the extra typing or copy/pasting of lines 14, 15 of the same code in your right side window.
@nielsdegroot9138
@nielsdegroot9138 3 ай бұрын
@@garyp.7501 You don't need to do that. The right side shows what the compiler makes of it behind the scenes.
@anjumlatif3052
@anjumlatif3052 6 ай бұрын
Video voice quality is not good.
@andreas_fertig
@andreas_fertig 6 ай бұрын
Sorry about that!
@almondengine
@almondengine Ай бұрын
so lets earn him a $5000 mic!
@zeez7777
@zeez7777 7 ай бұрын
NIce
@tomkirbygreen
@tomkirbygreen 7 ай бұрын
Very useful. Seems like it’s far from zero cost. Does noexcept get used much in (semi) realtime systems?
@andreas_fertig
@andreas_fertig 6 ай бұрын
Your move-constructors and move-assignment operators are typically noexcept. That's the reason why we have noexcept in the first place.
@davithov
@davithov 8 ай бұрын
First, thank you very much for the great lecture! I have a question: so we use integral_constant<bool, true> type, but isn't it possible somehow provide only value, i.e., for example `true`? Because we know, right, that `true` (or `false`) are of type bool? So IMO, it will be more natural to find a way to provide only values. Maybe should we use function templates to be able to deduce type? But, on the other hand, if I am not mistaken, starting from c++17 classes also deduce type, so maybe somehow can we use this?
@lev-th
@lev-th 6 ай бұрын
Difference is that integral_constant<bool, true> and integral_constant<bool, false> are of different types.
@andreas_fertig
@andreas_fertig 6 ай бұрын
With C++17 we can have "auto" as a non-type template parameter. This allows you to use a single parameter cppinsights.io/s/39165dba
@davithov
@davithov 6 ай бұрын
@@andreas_fertig That's fantastic! Thank you for the answer )
@davithov
@davithov 8 ай бұрын
So, in line 13 it is written min(m, ts....); Does that mean that at each step we reduce number of params in ts by 1 and pass it to 'b' ? it is also a bit confusing for me where exactly to put '...' . For example, why it is wrong to write like this: template<typename T ... >
@andreas_fertig
@andreas_fertig 8 ай бұрын
Yes, we reduce the number of parameters by merging the minimum of a and b into a. Then, we grab the first parameter of the pack and pass it to b, reducing the number of parameters in the pack by one in each iteration. To your second part, it is convention. The ellipsis goes right to the entity it belongs to. In your example, the typename.
@davithov
@davithov 8 ай бұрын
@@andreas_fertig Thank you very much for personally answering to my question! It is an honour for me.
@PaulTopping1
@PaulTopping1 9 ай бұрын
A default parameter on a function in the base class is still useful. It allows a no-argument call to have meaning throughout the class hierarchy. It seems like the real problem here is the compiler should not allow a different default value for the virtual function in a derived class.
@JaswinderSingh-dz1ui
@JaswinderSingh-dz1ui 9 ай бұрын
Great
@phusicus_404
@phusicus_404 10 ай бұрын
You can use #pragma pack to make members adjacent, but work with memory will be slower.
@ЮрійГордієнко-х2з
@ЮрійГордієнко-х2з 10 ай бұрын
Wrong
@JustABigFan2010
@JustABigFan2010 10 ай бұрын
Andrea 99% of the surface area of your video content is blank. And the most important parts of your video is in the top left corner which is only 1% of the area. Would you please on your next videos kind of focus on that 1%. Either make the font larger so that it kind of becomes the 50% of the video surface area. A lot of people with huge monitors make this mistake. We don't need to see the useless 99% of the blank area. For the people too comfortably see that 1% of the surface area they will need to buy large monitors same as you. So watching this video on a 15 inch PC monitor a tablet or a phone is basically useless because you cannot even Zoom in on KZbin videos.
@phusicus_404
@phusicus_404 10 ай бұрын
You can zoom a video on KZbin on a phone.
@JustABigFan2010
@JustABigFan2010 10 ай бұрын
@@phusicus_404 Write and we love reading source code on a 6 inch phone screen. Besides do you think the quality when you zoom in is going to be good enough to understand anything that you're reading in the source code. Don't be silly.
@AlfredoCorrea
@AlfredoCorrea 11 ай бұрын
Didn't think about this before. The key is also that std::string s{"Hell\0o"}; is not the same as std::string s = "Hell\0o"s; .
@andreas_fertig
@andreas_fertig 11 ай бұрын
That's a good point! However, the std::string consumer must respect the string size, not the null terminator.
@zuofu-ziv
@zuofu-ziv 11 ай бұрын
binge watching the series
@andreas_fertig
@andreas_fertig 11 ай бұрын
Awesome! Sometimes, I forget that I've published several episodes.
@zuofu-ziv
@zuofu-ziv 11 ай бұрын
very insightful!
@andreas_fertig
@andreas_fertig 11 ай бұрын
Thank you!
@reflec8525
@reflec8525 11 ай бұрын
thanks interesting insights. It seems initializer lists are not designed to pass by reference. Two other cases that are maybe more optimal if you avoid lvalues... Use move (if you have a move ctor): UInit c{std::move(a), std::move(b)}; Use temporaries to make the init list. maybe more the original thinking behind the concept: Uinit d{Unit(), Unit()}; //default, default, init list
@andreas_fertig
@andreas_fertig 11 ай бұрын
I agree, initializer lists are not designed to pass by reference. They are a view and not a container.
@David_Friberg
@David_Friberg Жыл бұрын
Note that this technique may unexpectedly break the rule of zero, in the cases where it would otherwise apply. As you declare the copy assignment op (even when explicitly defining it as defaulted) you suppress the implicit declaration of a defaulted move ctor and defaulted a move assignment operator. A mitigation comes with a cost: adding additional boilerplate code to bring us into rule of five, even if all special members are explicitly defined as defaulted. As an additional niche pitfall, it may also make aggregates into non-aggregates from C++20 and onward, as we need only user-declare a ctor to disqualify the class as an aggregate. Whilst this technique makes sense semantically, syntactically it can add a lot of noise, particularly in environments (automotive, safety-critical) where rule guidelines such as AUTOSAR C++14 (rule A12-0-1) will enforce rule of five if you cannot stick to rule of zero. Whilst this seems to have been addressed in MISRA C++:2023, I'm still leaning towards mitigation for to-rvalue assignment being enforced by static analysis (fully decidable) instead of via a language measure that comes with this kind of cost.
@VincentZalzal
@VincentZalzal Жыл бұрын
Have you seen any downsides to doing this? Does it prevent some common code idiom? I wonder if this could be made into a general guideline.
@David_Friberg
@David_Friberg Жыл бұрын
There are some downsides to this, but potentially the benefit holds their weight. See my comment above for details.
@VincentZalzal
@VincentZalzal Жыл бұрын
@@David_Friberg For some reason, I don't see your comment.
@davidf7196
@davidf7196 Жыл бұрын
@@VincentZalzal Seems KZbin's overzealously censored my comment, and does so even when I try to repost it. Trying from another account. What I wrote was: Note that this technique may unexpectedly break the rule of zero, in the cases where it would otherwise apply. As you declare the copy assignment op (even when explicitly defining it as defaulted) you suppress the implicit declaration of a defaulted move ctor and defaulted a move assignment operator. A mitigation comes with a cost: adding additional boilerplate code to bring us into rule of five, even if all special members are explicitly defined as defaulted. As an additional niche pitfall, it may also make aggregates into non-aggregates from C++20 and onward, as we need only user-declare a ctor to disqualify the class as an aggregate. Whilst this technique makes sense semantically, syntactically it can add a lot of noise, particularly in environments (automotive, safety-critical) where rule guidelines such as AUTOSAR C++14 (rule A12-0-1) will enforce rule of five if you cannot stick to rule of zero. Whilst this seems to have been addressed in MISRA C++:2023, I'm still leaning towards mitigation for to-rvalue assignment being enforced by static analysis (fully decidable) instead of via a language measure that comes with this kind of cost.
@David_Friberg
@David_Friberg Жыл бұрын
@@VincentZalzal For some reason my other (explanatory) comment keeps getting censored by KZbin, no idea why. Instead, I posted it as a Q&A on r/cpp_questions, hopefully you can find it there.
@VincentZalzal
@VincentZalzal Жыл бұрын
@@David_FribergFound it, thanks.
@stanbarvinsky1011
@stanbarvinsky1011 Жыл бұрын
great tip! thank you
@andreas_fertig
@andreas_fertig Жыл бұрын
My pleasure!
@TheBuilder
@TheBuilder Жыл бұрын
I'll think about it
@valentinsiltsenko
@valentinsiltsenko Жыл бұрын
Great tip. Thanks a lot!
@andreas_fertig
@andreas_fertig Жыл бұрын
You're welcome!
@ggladilov
@ggladilov Жыл бұрын
Is it the same with -O3? What does destructing an empty object mean? Would empty struct optimisation interfere here?
@andreas_fertig
@andreas_fertig Жыл бұрын
The example is too simple for the compiler with -O3. Still, in a code base that does something with the optional, it depends on the compiler's ability to see through it. In the worst case, the compiler performs a call to an empty destructor. That might not cost much, but the costs increase if it affects caching because the destructor is not in the hot cache.
@jaime7295
@jaime7295 Жыл бұрын
why C++ is so fucking cmplex XDD?
@AlfredoCorrea
@AlfredoCorrea Жыл бұрын
I don’t get it, the compiler can demonstrate that the body of the function will not be able to throw, so it will not contemplate calling terminate. So the code will be optimal in this case anyway. This video gives the opposite impression because it doesn’t say that all this will be optimized. I think the problem is when you say no except and you are calling a function that the compiler cannot demonstrate it cannot throw. In this case the compiled code generated will generate the call to terminate. I heard that there was an old argument in the committee and there was a faction (Abrahams?) that wanted plain UB for uncatched throwing inside noexcept and the other wanted a guaranteed call to terminate. The second faction won but there were some regrets afterwards.
@andreas_fertig
@andreas_fertig Жыл бұрын
There is no guarantee that an optimizer must do a particular optimization. This simple example compiler-explorer.com/z/TGeWcxrcf leads to code the compiler cannot efficiently optimize even though Other could simply return 2.
@mohammadghasemi2402
@mohammadghasemi2402 Жыл бұрын
Thank you. Are the contents of your videos also applicable to MSVC?
@andreas_fertig
@andreas_fertig Жыл бұрын
As far as I know, yes. It's mostly about work the compiler has to do, which results in longer compile times. We want fast compilers. A compiler that deliberately creates non-required objects just so the optimizer can throw them away will not be as fast as the one that creates only what is required.
@mohammadghasemi2402
@mohammadghasemi2402 Жыл бұрын
In the last example, why the compiler needs to increment and decrement acicp?
@andreas_fertig
@andreas_fertig Жыл бұрын
I'm not sure I understand your question.
@mohammadghasemi2402
@mohammadghasemi2402 Жыл бұрын
@@andreas_fertig In the video you said the reason why the compiler does not deduce the const after the pointer is that it wants to increment/decrement it. My question is why the compiler wants to increment/decrement acicp at all? Because that is what necessitates the removal of the constness from the pointer.
@andreas_fertig
@andreas_fertig Жыл бұрын
​@@mohammadghasemi2402 Sorry, that was badly phrased. The compiler cannot ignore the fact that the pointer points to constant memory. We also made the pointer itself const, by adding a top-level qualifier. Hence we cannot increment or decrement the pointer. That top-level qualifier is not part of the type. That's what the compiler ignores.