Thank you, Mike, for creating these insightful videos. I have a suggestion for future content: it would be incredibly helpful if you could produce a series of videos on build automation for C++ projects, covering topics such as Makefile, CMake, and Conanfile, from beginner to advanced levels. Your guidance on this subject would be greatly appreciated.
@MikeShah19 сағат бұрын
Cheers -- thank you Mohammad! That's at the top of the wishlist, it will come to this channel :)
@Onyx-it8gkКүн бұрын
Any plans for going in-depth with Rust or "making the switch"?
@MikeShah19 сағат бұрын
Not sure yet -- long term support for C, C++, and Dlang series will continue (as well as other series in game and graphics development). Rust is certainly a candidate language to go in-depth. The one constraint before I add another language series however, is that I have to use it for a project first to get a little experience 🙂
@gautam3978Күн бұрын
Can you tell where I can see those ppts that you have created?
@MikeShah19 сағат бұрын
Some are available on my webpage
@twenty-fifth420Күн бұрын
You know whats gets to me even to this day? I/O feels like night and day depending on specifically the language type. For Dynamic Languages, you get alot of sugar to control the standard in and out, fairly easily. I mean, your Python script can interact with your shell, so that isn’t too surprising. However, for Static Languages, you kind of get the minimum but it is standardized the standard libraries. I remember getting to C++ and having to use >> and std :: and I was sold on running the other direction. 😂 That said, now I am older. I see why C/C++ go this route. Since they are the lingua franca, it only makes sense for IO in the STD library to be implementation agnostic. One thing I kind of miss about scripting languages is you can just ‘print’ and it would just work. Or ‘read’ or ‘get’ or anything like that. Sure, you trade off the speed of compilation, but in iteration development, you can go fast in a Juypter notebook. Anyway, all that aside, never neglect that standard library! If I wasn’t able to read D, Swift or Crystals library, I dont think I would get past making my own reinvented wheel just to read and print. And C++, for all of the ‘kitchen sink’ it throws at you, I am sure that I/O library is very helpful is all systems donains. Namely drivers. edit: never forget that c header iostream! 😂Another thing thats gets me. Yeah, I miss D and Swift already 😂.
@MikeShahКүн бұрын
In some ways when learning programming, I think learning I/O in C first may actually be a big win. All languages seem to abstract on the C library. Understanding buffered/unbuffered I/O is somewhat clearer in C, and then folks can use and read other APIs in languages/libraries that may offer more convenience or otherwise speedup iteration time :)
@brajrajsingh10012 күн бұрын
can anyone comment about the original souce code of various standard classes in c++ like class vector, class string , etc
@MikeShah2 күн бұрын
They're certainly interesting to look at and learn some tricks from -- and over time they're very useful to study more to understand exactly how things work. The STL's goal is to be portable, performant, and generic, so that may impact readability of the code however :)
@Hailfire24552 күн бұрын
Hello Mike thanks for video I've a question that Currently I'm learning C++ so should i learn computer graphics stuff with resource you gave like raytracing in one weekend book and scratchapixel's website side by side with c++ or should i first complete c++ and then move on to these topics ., and thanks for your detailed C++ videos :)
@MikeShah2 күн бұрын
I would recommend first doing a little bit of C++ first. (Either this free playlist kzbin.info/aero/PLvv0ScY6vfd-R9N-vIDXdd4HO9IYATIxJ or this course: courses.mshah.io/courses/quick-start-introduction-to-modern-c-image-loader) Then as you said -- taking on a project to learn more. I highly would recommend the raytracingi n one weekend book, as it has the source as a fallback, and you can incrementally improve it as you learn more C++.
@Hailfire24552 күн бұрын
@@MikeShah thnx ❤
@MikeShah2 күн бұрын
@@Hailfire2455 Cheers!
@lorenzovonmatterhorn67732 күн бұрын
It keeps saying failed to load image. I am using WSL2. Has anyone got any idea why?
@MikeShah2 күн бұрын
Can you show exactly what you tried to compile and the full error message?
@vfjpl12 күн бұрын
That sizeof of pointer at 5:37 xd
@MikeShah2 күн бұрын
In Home Simpson's voice 'D'oh'. You're correct, since it's a pointer it is going to just return 8 bytes on 64-bit systems. If I had an array of characters array allocated on the stack it would have done the right thing. Good catch!
@bsdooby3 күн бұрын
In which cases do you prefer streams over the new print facility for outputting?
@sephirapple73172 күн бұрын
Streams could be used in many contexts, so it's a complex topic, and a long answer, but I'll try to explain. One of the crucial benefits of streams is that they store data in a buffer before writing or reading. First I will go through the reasons for using streams, what they can do and some examples of where they might crop up in the computer world. In a second comment below I will discuss the actual mechanics of stream buffering and the structure of streams and their data buffers. You first learn about streams in C++ with std::cout used to print messages to the screen. But streams are much more versatile. They essentially offer an efficient way to send large amounts of data (can be any type of data) when it is split into many smaller chunks. For example, you may have heard of "streaming" data "packets" across the internet to watch a video. This relies on streams. Imagine you want to send a letter with 1 million characters. If you put each character in an envelope and send it, it is slow, and very messy as the words may come through jumbled and disordered since theres no guarantee the post will arrive in order. So it's much better if you write all your characters on one sheet of paper, then send it in one envelope! This is the same with computers, data is slow to send and receive and it can also be difficult to assemble many pieces into order. But if you group many bytes into "packets" you can "stream" them over more quickly and they are already partly assembled into order so it is also easier to read the data on the recieving end, where it would be a complete nightmare to get the job done if you were to do this byte for byte. This can also be the case for sending a file, maybe a picture or video, from one part of memory to another. If you send each pixel one by one, the order gets messy and each transfer takes a long time without actually moving very much. It's much better if we grab a group of pixels, or maybe a frame of a video, and send them over in one piece, the data gets there without being too disordered, and each time you send something, the "envelope" is filled out to its capacity with more data so it will be faster than using a transfer just for onr pixel, when it could have been grouped with others and sent as a full video frame in the same amount of time. Or, say you're messaging someone, it doesn't make sense to send data over every time you hit a keyboard letter, it's easier to wait for you to finish the message and then send it off all together. All of these tasks and MANY others are done by using streams. The idea is that writing data immediately to the computer's main memory drive EVERY time data is available, but maybe only sending a few bytes, is a huge waste of processing power! It's far more efficient, fast, and easier to manage, if you hold on to the data for a while, keeping it in a temporary buffer nearby while the program adds bits and pieces to it, which is quick since the buffer is nearby. When the buffer is full or there's no more data to add for a long time, then all that data can be packaged and sent off as a single coherent block of memory to be written over to a desired location. By sending data in large unified batches in this way, efficiency is HUGELY boosted compared to sending a few bytes here and there as they become available. This is not very noticeable when it comes to trivial tasks like printing the typical "hello world" to the screen because there isn't much data to write in the first place. Even if its done bit by bit, it's still very fast regardless of how you do it. But when it comes to larger data blocks, the efficiency gains become vital! Loading millions of pixels into a graphics card on a video or a 3d program would be all but impossible if you did pixel by pixel, but by batching up pixels into blocks of data to be "streamed" over to the GPU, the task becomes very manageable and it doesn't take the computer 10 days to work out how to put together a simple video, because most of the data already came packaged in a neat and predictable flow when it was being delivered from the main memory! That is the idea behind data streams and what makes them such a powerful and indispensable tool in the C++ language, and that is why they are well worth learning about in the long run when it comes to assembling increasingly complicated programs and projects!
@sephirapple73172 күн бұрын
I've gone through the broad ideas behind WHY streams are helpful and the kind of things they are used to do, so now I will explain in greater detail HOW they actually achieve their goal and the mechanics and functionality behind streams and data buffering! Accessing hard drive memory is very slow and inefficient. Streams add small blocks of data to a larger data buffer, then they can save or load the whole block in one go, so access to main memory (usually a file) is done less often, in bulk. Storing small chunks of data to a buffer and transferring it in one block is MUCH more efficient than regulary transferring many small blocks of data every time. "Output" streams store "write" data in a local buffer and then "flush" to a file when the buffer is full. Now the buffer is empty and ready for more "writes". "Input" streams work the other way: a block of data is loaded from a file to the stream's buffer, then data can be "read" from the buffer when needed. When empty, the buffer loads another data batch from the file so more "reads" can be done from the buffer. This is very useful for adding together small chunks of data to be transferred as a single larger block to or from the main computer memory. This reduces the number of slow memory accesses, because a local buffer works MUCH faster than accessing main memory. The buffer only needs to access memory in bulk. Without a buffer, this would be done EVERY time you read or write data to a file. It should be noted, stream "buffering" is done internally. When you read or write, the buffer is loaded and flushed automatically; it is rarely accessed directly. If desired, a buffer CAN be manually assigned right after creating a stream, but the system will do it for you. You can also manually flush the buffer when you like, but the buffer is automatically managed by the stream, so flushing is usually not needed. The buffer is not often used manually, but knowing how it works is VERY helpful for understanding how streams behave! Streams use pointers to track position (eg file position for file streams). tellp/tellg return the number of bytes from the start of a file (or string) while seekp/seekg are used to move the position pointer. tellp and seekp work with the "put" pointer, which is where to write into a file; tellg/seekg are for the "get" pointer, the position to read data from. I like to use separate ostream and istream objects to access a file (or string) to keep write and read operations separated. That covers most of the basics of what streams do and why they are useful! Different types, like string streams or file streams have some extra functions, but the underlying concepts are the same for all streams! Hope this helps you to understand what streams are all about! Best of luck learning this stuff, it's a challenge but well worth knowing about!
@fuji_films2 күн бұрын
@@sephirapple7317 thanks mate for you time. ❣️
@bva02 күн бұрын
@@sephirapple7317 Mate, thanks for your time, that was a great explanation!
@MikeShah2 күн бұрын
@@sephirapple7317 Better than I could have explained -- thanks for taking the time!
@iamdodo27383 күн бұрын
Huge respect for your videos
@MikeShah3 күн бұрын
Cheers!
@peterwolfinger62893 күн бұрын
There has recently been an inexpensive book about FreeBASIC in German available on Amazon. See www.amazon.de/dp/B0D3JY3VK8
@uvideo1003 күн бұрын
Hey Mike, Just a typo in your drawing at 2:57. You mentioned storage space for type integer is 4 bytes, but you drew a box of 5 bytes. It is a pretty obvious typo, but could confuse some new learners. I am trying to get from intermediate to expert at C, and find your videos very useful. By the way, does integer type always require 4 bytes of storage, or is it compiler dependent?. Do some compilers allocate 8 bytes to store an integer? Thanks!
@MikeShah2 күн бұрын
Good catch! Generally speaking, it is compiler dependent on the size of the 'int' type. There exist 'fixed-width types' that may be better for portability that otherwise are consistent -- you can learn about them here :) kzbin.info/www/bejne/joOZoJmLpc-ZeJY
@sephirapple73173 күн бұрын
Look forward to seeing more tutorials about io streams! I'm putting together a software framework based on SDL libraries; currently implementing a 'Log' class based on the SDL logging system. It's been a challenge to learn about streams, buffering and working with files. I'm very keen to see your insights as it becomes increasingly relevant to my projects! Love the channel, it's one of the best C++ sources on KZbin! ❤️
@MikeShah2 күн бұрын
Cheers -- thank you for the kind words. Next video added more to streams :) I have some ideas in the gaming space for doing more talking about buffering. The problems start getting really interesting (i.e. tradeoff of encoding/decoding to save time) when you also compress the data for speed purposes in gaming :)
@guilherme50944 күн бұрын
👍Mike!
@liam_iam4 күн бұрын
I guess this is a question not just about C++, but I'm wondering how these dynamic data structures (like vectors) work. As a vector grows and grows in size, and assuming that those elements are stored contiguously in memory, how does C++ prevent the memory stored by those elements from "colliding" with other data stored further along in memory? For example, if we have a vector stored at position 0x0000, and some other int stored at position 0x1000, if we added enough elements to the vector then surely it would approach 0x1000.
@MikeShah2 күн бұрын
So vectors for instance use 'new' to allocate memory. 'new' is a memory allocator so it has its own data structures to manage where memory is. If we need a bigger chunk, then we'll free that 0x0000 - 0x1000 block, and allocate whatever block is big enough and not previously occuppied. This can indeed present some interesting challenges of 'how to find the bigger chunk' (Well operating system hands it to us effectively), or what type of 'fragmentation' (little free bits in between) may occur. These are all great topics of studies in 'systems programming' that further go into these details. Note -- Again, there's another level of abstraction, as from a processes perspective, we just assume we have a bunch of memory in a linear array -- the operating system has its own allocation of 'heap' memory.
@NSA-n8n4 күн бұрын
Just starting but so far, your formatting and teaching structure is great :)
@MikeShah4 күн бұрын
@@NSA-n8n cheers!
@GaryChike4 күн бұрын
Very cool coverage!
@MikeShah4 күн бұрын
😁
@VoidloniXaarii5 күн бұрын
Thank you so much for this! So appreciating your every c++ lesson 先生
@MikeShah18 сағат бұрын
You are most welcome!
@keertichaudhary92575 күн бұрын
really good playlist. would like to see more related videos on this.
@MikeShah5 күн бұрын
Cheers!
@niravpatel12395 күн бұрын
Important point is , how should we delete that object? How destructor will be call?
@MikeShah2 күн бұрын
This is indeed a good question -- because now we effectively have 'two' ways to refer to the same object. Generally speaking, the lifetime of the reference will not effect the original variable unless we explicitly do something -- 'ref' otherwise just goes out of scope in our example. It so happens that 'ref' is in the same scope as 'x' that it doesn't matter here. If the 'reference' takes over ownership of the object, then it can be deleted however through that reference in the case of an object allocated with 'new'. In C++11 we have 'move semantics' which allows ownership to be taken over (more important for dynamically allocated objects with 'new' for instance -- see kzbin.info/www/bejne/aJi4oqyqaq-Hqq8& for an introduction to move).
@damondouglas5 күн бұрын
Thank you so much for this series. I really like how your examples build off each other so its easy to introduce the new concept. As you said, it's hard for our brains to compute concurrently
@MikeShah4 күн бұрын
Cheers -- thank you Damon!
@wrymeanders83825 күн бұрын
Thanks for the overview. I love the description of the "Marks" book as something you can curl up with and read! I'll have to get a copy now :)
@MikeShah5 күн бұрын
@@wrymeanders8382 cheers, you are most welcome!
@MrPetzold1235 күн бұрын
Thanks a lot ! I've been fearful of doing that but now with these instructions I'll try to compile my way to c++23 niceties 🤩 !
@MikeShah5 күн бұрын
Excellent!
@user-cq4zk8mw6r6 күн бұрын
Hey, good man, what about you.
@bsdooby6 күн бұрын
a nice and handy feature; would be cool to have coverage reports parseable by some dashboard software (e.g., SonarQube, etc.); maybe a project for students...
@MikeShah6 күн бұрын
Indeed -- I think tooling could be nicely built for a dashboard for larger projects. DMD as a library project will certainly make some of this tooling more easy. over time as well!
@MikeShah8 күн бұрын
Here's a quick snippet for retriving the attributes for unit tests (i.e. the 'names') if you want to extend this further. Note: Even better if you can grab this information at compile-time and populate an AliasSeq -- see if you can do it :) void main() { import std.conv; alias tests = Tuple!(__traits(getUnitTests, foo)); string[] attributes; foreach(test ; tests){ attributes ~= to!string(__traits(getAttributes, test)); } //writeln(attributes); foreach (idx,test; tests){ writeln(idx,".) ",to!string(attributes[idx])); test(); writeln(); } }
@bsdooby8 күн бұрын
why is `foo` printed two times? I would have expected `foo` and `foo2`?
@MikeShah8 күн бұрын
Will pin a post to otherwise get all of the unit tests properly named.
@guilherme50948 күн бұрын
Thanks Mike👍!
@MikeShah8 күн бұрын
Cheers!
@twenty-fifth4208 күн бұрын
Lol, I was just thinking if unittesting can be meta/reflective. I was thinking of making some tests for my OpenGL state machine exercise that can automate various testing stages of the pipelines. Actually wanna take it further, but that was the simple of it. What I would love as a programmer and potential programming language designer is to just make any function isTestable? and give it optional parameters. The amount of asserts and tests I do just to say “okay now test this parameter, but do not use 0 because that will fail because I said so”.
@MikeShah8 күн бұрын
The meta programming for pipeline based APIs could indeed be very powerful!
@GaryChike8 күн бұрын
D First!
@caiodavi98298 күн бұрын
thanks! it helped me a lot
@MikeShah8 күн бұрын
Cheers!
@georgiosdoumas24469 күн бұрын
11:34 , I think that destructor should not have any parameter list!
@MikeShah8 күн бұрын
Indeed -- copy & paste error without actually testing (just in the 'discussion' or 'sketch' portion of the video). I'd need to think a bit about a use case for a parameter in a destructor -- perhaps for control flow on how you'd like to perform deletion for instance -- but the mechanism may not work as well as 'defer' or 'scope(exit)' in other languages.
@udance4ever9 күн бұрын
thank you very much! I'm another step forward to getting this project built - one more library (VLC) to build from scratch to go!
@MikeShah9 күн бұрын
Cheers!
@SamOaks9 күн бұрын
auto is silly
@MikeShah9 күн бұрын
Using it for regular variables probably is -- useful for local scope and generic programming however
@salio46719 күн бұрын
Came here to update my knowledge about pointers, great explanation as always thanks. For me pointers are very similar to shortcuts in windows for example, just in a smaller scope. They both store an address and both reference to something whether it is some value or an executable, the idea is similar. They are not that hard as they seem to be, tho for many beginner's they are something unthinkable. But the idea of shortcuts in an OS for the same beginners is something intuitive.
@MikeShah9 күн бұрын
Cheers! Nice analogy :)
@kcvinu9 күн бұрын
Is it good if a library developer uses static asserts for error checking in his final output ? By "final output" I mean the code I uploaded to my repo.
@MikeShah9 күн бұрын
static asserts should not have any runtime cost for the final product, as they are just executed at compile-time and otherwise stop the program from compiling if they do not pass. static asserts otherwise I would encourage folks to have, and you don't necessarily need to hide them in your implementation. Some folks do hide the test suite however, if that gives away critical information for some reason.
@kcvinu9 күн бұрын
@@MikeShah Got it. Thanks Mike 😀
@sanjaygatne14249 күн бұрын
time 3:13. Why not even "read only" access to global static data is allowed in pure function.
@MikeShah9 күн бұрын
If you make global 'const' or 'immutable' this is fine. The reason we cannot allow 'int global=3' otherwise to be used in pure functions is because if we have multiple threads then global data could be modified elsewhere, and thus the function would not be pure.
@MikeShah9 күн бұрын
See more with pure here: kzbin.info/www/bejne/hnK7eYJ7qsuJfK8
@bsdooby9 күн бұрын
I watched this episode again; why isn't the compileStatic function not called twice? ah, I see: you did not execute the actual program 😅
@bastiaan912710 күн бұрын
I finally had time watch to the end, and loved it. A very enjoyable interview!
@MikeShah10 күн бұрын
@@bastiaan9127 cheers!
@JumpercraftYT10 күн бұрын
This is probably the best opengl series on youtube. It helped me a lot on graphics programing. Recently, i've added bindless textures on my laptop. It works just fine, but when I pushed to github, downloaded it and used it on my PC instead of my laptop, I still see the stuff, but not the textures. So why is it only working on my laptop but not my pc.
@MikeShah9 күн бұрын
Cheers, thanks for the kind words! Perhaps your laptop and PC have different graphics cards? Bindless textures as I understand are an extension, and not part of core OpenGL 4.5 or 4.6
@JumpercraftYT7 күн бұрын
My laptop has a 3050 ti while my PC has a 7800xt
@MikeShah7 күн бұрын
@@JumpercraftYT Might be an issue of updating drivers then. What version of OpenGL is supported on each?
@JumpercraftYT5 күн бұрын
Version 4.6 on both. Also, i tried adding texture arrays instead of bind less but it only worked on my amd gpu instead of my nvidia, which is weird.
@MikeShah5 күн бұрын
@@JumpercraftYT Strange -- I've had the misfortune of having the integrated GPU being the default selected GPU on my machine and that also has caused differences.
@georgiosdoumas244610 күн бұрын
18:50 in the for loop, it would be even better to have it as for(const auto &e : m_messages) since the element is accessed only for reading and not for modifying it!
@georgiosdoumas244610 күн бұрын
30:35 ,the usage of words "move " and "undo " was confusing for me, but I translated in my mind as (and that is the output that I would rather see) : "move by x and y" and instead of undo : " move by -x and -y ".
@MikeShah10 күн бұрын
Since the value of the move that is being written is not what is being output(i.e. c.x and c.y), x and y still need to be negated.
@bsdooby10 күн бұрын
Learned a lot, too ;)
@MikeShah10 күн бұрын
Cheers!
@bsdooby10 күн бұрын
Learned a lot 🎉
@MikeShah9 күн бұрын
Excellent!
@twenty-fifth42010 күн бұрын
It is weird I didnt get the notification for part one. But related, testing makes ‘computer science’ feel like ‘science’. Plus, I think we all started in the broad sense ‘testing behavior’ in some repl of some kind. Soooo you just type your expression and find out what happens 😂. Of course, this is not software testing, more empirical testing. That is my thoughts though. Anyway, neat we have made it past 101 episodes. Maybe I should watch this series one more time..
@bsdooby10 күн бұрын
Me neither (?)
@MikeShah10 күн бұрын
Not aure why the notification did not go out -- maybe a big from KZbin @@bsdooby
@Surasia10 күн бұрын
Would this be useful for defining simple magic numbers? so instead of #define MAGIC 1000 constexpr int value = 1000 in some sense, would it be more "C++-y" or would a const be enough?
@MikeShah9 күн бұрын
Generally speaking, I prefer 'constexpr int' versus #define, as the defines are just a textural replacement, and you get the advantage of typecheck. Constexpr also sort of 'forces' a constant propogation or other evaluation for more complicated magic values alongside the stronger typechecking. Depending on your debugger as well, #define's may not expand well (unless you use -ggdb for gdb for instance) either, as the 'magic' value gets lost.
@Surasia9 күн бұрын
@@MikeShah thank you! your channel is a great resource
@GaryChike11 күн бұрын
I remember asking Wouter if this is a good beginning language and he said no. And since there is dearth of tutorials on Lobster, this language is essentially built for more experienced developers that has experience in another language. 🦞
@MikeShah10 күн бұрын
I could probably agree with that. Given enough tutorials and some fun graphics/game themes perhaps it could be over time if folks wanted to learn it as a first language. Generally speaking, I still recommend python as a first language -- or even D 🙂
@CptBaconNipple11 күн бұрын
Sigh... use the HDMI port for the ZV1 and connect it to a CamLink. If you use the USB to connect it to your computer, you're stuck with this bad quality.
@marks20911 күн бұрын
why cant i find this documentation that you have opened, it looks like they removed so much from the sdl wiki
@MikeShah11 күн бұрын
@@marks209 I think for sdl3 that might be the case. There may be a mirror to the sdl2 docs elsewhere otherwise
@androth150211 күн бұрын
i tried lobster a couple years ago. it's a great 'batteries included' type of language. i just, at the time, didn't find the pythonesque syntax agreeable.
@insadeyt12 күн бұрын
hey mike, iam super new to programming and my question is that what is size_t?? i ve learned so much from this playlist. all thanks to you but i am so confused at this point what in the world is this? size_t and vectors
@MikeShah12 күн бұрын
Welcome! size_t is an 'unsigned integer', usually an unsigned long or some type that can otherwise hold lots of integer values. By convention we use it to ensure we don't access a negative index, as well as to indicate a 'count' or 'index' of something