Imagine if the linker was a human though.. what a horrible job. Linker: Mate, seriously, for the fifth time today where is the multiply() function? Me: Wha.., it's not there? Linker: ...No Me: Are you sure? Linker: YES, I AM SURE! Me: can't be, check again. Linker: AGHRGR Me: Ooops, accidentally typed it as mltply().. lol
This is one of many examples as to why IDEs like Visual Studio are indispensable time savers. Typos are almost a non issue when you let go of your ego and use IntelliSense.
This finally explain why we just declare things in a header file and only give one definition in cpp files, because that way the linker always find the right one when linking functions. And the #include just make that file knows the functions exist. I didn't get it since I started programming 2 years ago until now. Thank you so much.
There's so many examples of this in programming, primarily because it's such a practical subject. Crucially, we NEED examples in order to learn how to do things and there's many different ways to achieve the same thing. I also think with the internet/Google there's the risk of 'information overload/burn'. In the end, though, an inquisitive mind helps immensely - particularly as you are learning the language. A 'natural' programmer i.e. someone who genuinely loves programming and learning, is pretty rare (as opposed to someone doing it only for the job/money). In this channel, we appear to have that rare thing, a natural programmer. Definitely worth following.
@Fabulous Rogue At the stage of compiling main.cpp, you don't need the "definition" of Log function. But compiler will check if it has been "declared" properly (otherwise it can't generate the information that obj file need). Linker will then actually put all obj files together (of course there are more jobs to do besides this) to make the final executable so that when your Log function get called it can actually jumps to the definition part (machine code). Yes, essentially it needs function definition to run the code, but that will happen when it's at linking stage instead of at the stage of compiling each translation unit.
@@shubhamdhingra6089 At the compilation stage all that is run is code which does not depend on any variables, as this code CAN be run before the variables are known. So, code like 5 * 2 will be simplified to 10 during the compilation stage. Any other code, which includes functions of variables, is run at run time. This run time is after the linking process. The linker knows to look for declarations of functions, as without a declaration it doesn't know what a function is and can't link it to a definition, and without a definition the program won't run after linking. After finding this declaration, it requires a definition. However, at this point, the linker has linked the files, as it has found declarations for each of the functions in each of the files, so when it looks for that definition, the definition can be in any .cpp file which was included in the linking process.
Short Summary: After Compilation, we need to go through linking. linker finds each Symbol and Function and stitches them together to make an exe file. Multiple Obj files can’t interact with each other so if we have split our program into multiple C++ files they need a way of linking them together into a single exe file and this what essentially a Linker does. Even if u don’t have multiple files linker still needs to link main function. It needs to know the starting point of your program. He gives example by creating a file that didn’t have the main function, this file compiled successfully however when linking it generated a linking error saying entry point not found. There are different error types for Compilation and the linking stage in VS. It begins with C for compilation and LNK for Linker error. For example, a syntax error is a compilation error, and the main not found is a linker error. As in project property, the config type is set to .exe file and every exe file must have an entry point we need to specify an entry point by default it is the main function. we can specify a custom entry point in linker > advanced > entry point Then he explains about a specific type of Linker error called “Unresolved external Symbol”. This basically occurs when the linker can't find the specific symbol. watch 6:58 can’t explain it in words. Writing static in front of a function implies that we’ll only use that function in that file only. For the linker not only the function name is important but also the parameters and return must match 100%. If you define the same function twice in the same file compiler will generate an error because the compiler works on one file and it can detect it. however, if you have the same function definition in multiple files the linker will generate an error because the linker doesn’t know whom to link to the call. This is the reason why we keep function declarations in .h file and not the whole definition because if we do so we can’t include that .h file in multiple files because that’ll generate linker errors.
The whole series is fantastic! I wish they thought C++ this way back in my student days. Sometimes it seems like those teachers did not even know what they were talking about...
@@groberti I currently have the same issue (German school system), not even "#include " got explained at all or barely any basics to know how everything works. I'm infinitely happy to have found these videos!
@Fabulous Rogue That's the entire reason for why C++ has header files. When you include a header it's contents gets copied into the file that includes it. The when the compiler reads it it will find something like void func(int); and think "okay, this function exists". But there is nothing special about where you included it from, so if you just write the contents of the header in your cpp file the compiler won't know the difference.
@Fabulous Rogue So basically the cpp files and h files are completely separate, h files are just convenience, and through definitions you tell the compiler that something does indeed exist, but in another cpp file. So likely your problem is that you're only giving the compiler main.cpp, but you also need to give it Log.cpp
I love that you teach the concepts through errors, as it's all good and well understanding how something works, but understanding what breaks it is far more crucial in most cases. Thank you for this series. I'm aiming to learn C++ from a Java / C# background and finding it incredibly easy to grasp the differences with your guidance. Kudos!
I totally agree, because the thing that gets frustrating when you're learning especially is suddenly running into an error like the ones he shows in this video, and then not having any clue what the problem is or how to fix it. This is honestly such a nice way to teach and to show common problems to help people who are learning. I'm coming from a C# background and learning C++ now, I hope that now 3 years later your C++ experience has been going smoothly!
This guys fucking GOAT.He doesnt waste time on pointless shit,straight to the point.Plus he has a very distinc auratic music behind.Also he teaches lots of good stuff nobody mentions
I just started learning programming 2 weeks ago, and this is by far a really great explanation (of what happens behind the C++ scene) that can be understood by a total beginner. Thank you!
@@Brad-qw1te This is the kindest RUclips comment I've received so far! Thank you so much, internet stranger! I truly got this! btw, I am not smart. I take notes and listened to his video repeatedly for an hour or two (in.75 speed) - until I get it. I also research terms I don't understand, and have finished FreeCodeCamp's C++ tutorial. It's very overwhelming for me, but I am enjoying learning about it so far. So thank you for your advice. I do take everything like a grain of salt, and just intake what I need to know (for now). I'm wishing you luck too! You got this!
These videos are by far the best programming series on RUclips, I watched them a few years ago and find myself re-watching them after not touching C++ for a long time. Very well, thought out videos.
Dear Cherno, I am amazed by how you manage to give us awesome tips and tricks even when covering "simple" concepts. such as linking. You truly inspire me to dig deeper into the language, IDE, everything. Keep doing an amazing job!
This was a very well made explanation video. I'm going to recommend this to some professors maybe they'll use it in class. The only thing I didn't hear you mention, and perhaps because it's a C++ series, but linking also is when you bring in code from other languages. This is important because it's very possible to take libraries from/for other languages and use them in C++ by linking them correctly and including the proper declarations.
@@luisgeniole369 So maybe you got a bit confused. But I think you remember when he said that the extension in c++ files doesn't really matter. .h and.cpp are both cpp files
I know why he left it out. As he would have to address "name mangling" and as there's no standards for how names are mangled by a compiler, every compiler does it differently and it's a nightmare. The thing to realise about the linker is that it's actually language agnostic. It deals with object files, and object files are basically the actual binary machine instructions that a compiler translates your source code into - plus other necessary bits of information about what symbols are defined and where they are in the file (so that when the linker links, it looks up these symbols and then inserts the correct addresses in the right places to physically hook up these object files together). (Indeed, back in the day, when doing some assembly coding, I had an assembler... and then I just used the linker that came with my C compiler to do the linking. Your compiler will come with its own linker, but linkers are not tied to particular languages - object files contain the final machine instructions - and so I could "borrow" the linker with the C compiler, even though I was linking stuff that wasn't compiled by the C compiler. You can probably grab the linker that comes with some other language compiler and use it to link your C code together. Object files and linking happens AFTER everything's been translated into machine instructions. At that point, all object files are basically the same, regardless of what language they originally came from.) The C++ compiler will take the source code and generate its object file. But, equally, if you used, say, a Pascal compiler with some Pascal source code, then it'll generate an object file out of that. The linker doesn't know what language compiler was used, it just takes object files - which is basically just the final binary machine instructions, plus some "metadata" about where everything is located, so that it can take the address of a function from one object file and then insert that address into the "call" instruction of the other module to physically link them together. So, like, all (compiled, but not interpreted) languages end up producing object files and a linker stitches those together. And, to the linker, it doesn't know - and it's irrelevant - what language the source code the compiler translated came from. An object file is just binary instructions and then some additional "metadata" about the symbols in that file, so that the linker knows where the functions and variables are actually stored in that binary, so that when it stitches the object files together, it can look up the symbol - such as "_main" - get its address and then hook up the "call" instruction from the C++ startup code to call your "main" function. And, yes, you'll notice that the symbol name has an underscore. This is C's naming convention. It sticks an underscore in front of the function or variable name. Which is nice and simple, yes. You have a C function called "myAwesomeFunction"? Then, in the object file, it's symbol name will be "_myAwesomeFunction" and that's what the linker will try to hook up with other modules. (Why add the underscore? Because this guarantees that any functions / variables defined in C source code can't conflict with other symbols. In truth, the real "entry point" in the executable is usually called "start". C / C++ will add "startup code" to the object file (this code is responsible for setting up any initialisations that need to be done before "main" runs) and then it calls "_main". That's what's really going on under the hood, but you don't have to know this - the C / C++ compiler will sort that out and add the "startup code" by default - unless you start messing around. Like folks who enter those "64K demo" competitions often play around with this stuff, because you can save many bytes by dropping the standard "startup code" and writing your own lean and mean assembly functions instead. Indeed, on modern compilers, the startup code and standard libraries included by default will often immediately break the 64KB limit that such competitions impose. So you've got to avoid this stuff or you'll have very little or no bytes left, within that 64KB limit of the competition, before you've even hit "main". I do love a good 64K demo. Watching how "extreme" coding can get, when somehow these people squeeze amazing expansive stuff into a space that many C / C++ compilers already break, just reaching "main" and doing absolutely nothing at all.) Yes, I said "C naming convention", distinct from the C++ naming convention. That one is a bit of a nightmare topic. Because, in C++, you can have function overloading (different functions with the same name, but taking different parameters). So, to support this, symbol names get "mangled". And, yes, after you've seen what mangled C++ symbol names look like, then you can understand why the term is "mangled". The slight problem here is that there is no C++ name mangling standard. Every compiler does it differently. It's a nightmare. So much so, what almost always happens is that you declare things as 'extern "C"'. What this does is tell the compiler that this declaration follows the C naming convention (just add an underscore in front of the name in the source code and, no, you can't have two functions with the same name under C conventions, so you have to give that up for 'extern "C"'). Because C does have standardised naming and calling conventions defined. So what you find is that most languages have their 'extern "C"' equivalent to define that a function / variable should be exported under C conventions and then it's easy to make things link up. C convention is just the name with an underscore in front of it. So that's the symbol name sorted. And then "_cdecl" defines the calling convention. Anyway, you're starting to get the picture. This stuff gets complicated fast. Name mangling is a nightmare in C++. This topic is interesting, but it needs its own video - actually, possibly a series of videos - to explain and it's rightly kept out of this "introduction to how linkers work" video. And, in practice, as I say, what usually happens is that things are declared 'extern "C"' so that they get exported following the C conventions. Because those conventions are well-defined, standardised and simple. And most language will have their 'extern "C"' equivalent and, by and large, all languages meet each other by all adhering to C conventions. Basically, because the C standards bothered to clearly define these things and it's comparatively simple. While every C++ compiler mangles names in different ways, and other languages are also like that - different compilers doing different things, making things incompatible. So the usual trick is that everyone just uses "C convention" as the "lingua franca" for interoperability. Otherwise, with every compiler of every language doing completely different things, then getting them all to meet up is a nightmare / complicated / sometimes simply impossible.
This is the best C++ series on RUclips. Incredibly enlightening. Even though I studied C++ in college and have been using it at work for the past 3 years, I often miss the nuances of the compilation and the linking process. I feel like I am in college again!
Really like your videos. You have the C++ language, CS theory, practical hands on stuff like how to optimize work with VS, experience from an actual professional, low level assembly and memory, all combined with a good presentation.
In retrospect, not understanding linking errors is why I have failed to learn C++ in the past. I always had to give up with C++ from not solving the compiler and linker errors once a project got complicated. I didn't even know there was a "linking error". Your videos have fixed all that. Excellent job Cherno! Elon Musk once said that to understand the tree leaves, you must first understand the tree trunk and limbs. You have placed this concept into action by exposing us to these typically confusing errors early in the training. Thank you, thank you very much.
Somehow landed back here in 2023 and this still is the best c++ series out there. People mostly want to learn c++ to get a job but neve want to know the in depth version of it's working. There is no limit to human stupidity. @The Cherno You are awesome!! I hope I can contribute to hazel in a couple of months!!
Doing C++ at university, and had questions like 'how does a compiler work' and 'how do you write multiple C++ files and a header and this is beautifully done. Sure, It's not directly relevent to the course, but gives a better understanding which in my opinion helps alot with standardizing code to be more professional and standard.
I feel like this series is exactly what I needed after learning the basics. There's so much more to C++ that our brains just weren't ready for back when starting.
Now this is what i call worth watching tutorials! You explained SO MUCH to me! Thank you! Now i understand how libraries are included like 'inline style', how and when Linker works, and that i can put whole definitions into header files (which of course is not a good practice). You make great job not only for beginners but for everyone who on some level missed some knowledge. Yours is awesome. Keep goin' and one again GREATEST THANK YOU CHERNO!!!
I can't thank you enough for this series, the amount of knowledge you are able to deliver in 15-20 mins about one topic is just amazing to say the least. At the starting I found it a little bit fast but now I am able to keep up with the pace.
This is a great series. I really love the way on how you are showing things practically instead of just saying it out and also giving example of error that programmers do. It really helps understand the concept well and combine them.
I am so upset when i look at the subscribes. WHy it is 100k ???? You deserve more than that !!!!! I saw gamers whose doesn't give any value for the world but hey keep watching them or giving them money. That hilarious, they make no sense. But you, you give the world what they need, you do this by your passion, you make me learn so much from you and make my coding skill better ( which is my passion too)!! So KEEP GOING BRO !!!!! I want that number to be 1 000 000 000 !!!!
Personal notes for myself when reviewing video again: - static makes that function only declared for that translational unit(the cpp file you are in), i.e. linking is only internal - if two different files have functions with same name(signature), then you get linking error saying it has multiple definitions
I swear if I had these videos when I was first starting out in C++, it would have saved me manh hours of debugging code due to me just not understanding how to read linking and compiler errors properly.
You're tutorials are the best I've seen on RUclips, period, you explain lots of theory and go into detail.. but one huge question..... when the last time you blinked?
Thank you so much. This playlist is the most comprehensive C++ playlist I’ve ever come across. I’m curious if you’ve covered the topic of writing makefiles for C++ programs. If not, I would greatly appreciate it if you could teach it in the same manner as your other playlists, or provide a thorough resource for me to study. As a Computer Science student, I’ve struggled to find a complete guide to learning makefiles.
I ran into the issue of defining a function in my header file then used the header in multiple cpp files and couldn't figure it out, thanks for that solution!
I always felt that concept of components of language processing programs I had learned were quite up in the air. really needed in-depth context on how the each components work. and i found your video and i love it so much ! thanks~~~ 😀
Wow,it's really insane that it contains a lot thing that i never get clearly from the book,it shows that how to creat a c++ program instead of how to complete a program.It's useful for me.
A lot of things start to make sense now! EG how you always made a header file including nothing but the declarations during Sparky. Great video, I really feel that this series is way better planned out than the previous ones.
#include "log.h" is present in log.cpp & math.cpp,that causes linking error. #include is also present in log.cpp & math.cpp. But why that doesn't cause any linking error?
In Log.h, the function is declared as well as defined. I believe in , all the many functions are only declared, and the definition is elsewhere. If I "#include ", I guess I'm copying and pasting a lot of function declaration, telling the compiler that those functions exist. And the linker will find those function definitions for me. If anyone thinks this guess is wrong, please point out.
iostream has ‘#pragma once’ compiler directive which essentially tells the compiler to include only once and if encounters other instances it just ignores.
@@spocksear7616 This is incorrect, #pragma once only saves you from including the same file multiple times in a single translation unit. It is explained in Cherno's video on header files
Very good and explanatory. Everyone else doing tutorials go straight to coding without deep explanation. You need to understand in order to code good ;)
Could you please make a video on circular dependencies? :) I'd like to understand them better, to be able to avoid them. You're doing a remarquable job, please just never stop!
"Now you might think this kind of error doesn't happen often and you're smarter than that" My famous last words before I started coding and getting to know Dunning-Kruger ^^ Nice series btw
it is a shame for me because I found this channel so late and it is a shame for you there is no education for c# like you did for c++. great tuts. thanks
This is an extraordinarily good video! I love how you managed to blend together the basic concepts and faults behind error with more practical examples of how they may happen in the wild. Great job!
Yet another wonderful tutorial by Cherno. Best video I have ever seen on this topic. Clear, concise and full with enlightening information. Congratulation!
amazing work !!! after near 2 years of coding experience in c(uni experience) finally i can understand linking and compilation . Thank you ! you explained this well and much better than in Academy course's for Shure
So afar what i understand after two c++ tutorial...is simply because in c++ after compiling all files will get combined in one file and double declaration (#include) of same thing means you are defining twice same object/function. different than javascript where double declaration gets replaced with the last one. pretty much standard so far.
At 14:31 we are including the log.h file which calls the log function, but since there is only one definition of log function in the whole project there is no error.
can u do a series on Linux stuff and one on Architecture including assembly code? you know a lot about low level stuff which is especially confusing to most cs learners. great channel!
This series is a masterpiece.
+++1
++++1
+++++1
++++++1
+++++++1
Linking is fun, but have you tried blinking? =))
@ibnol waqt he does blink at around 0:52
@@TheBrainReal close but no he doesn't
@@sanketshah9759 ah no now I see. He just needed to go 0.1mm further for a blink :D
@@TheBrainReal yeeeep
haha this deserves 9000 thumbs up :D
Imagine if the linker was a human though.. what a horrible job.
Linker: Mate, seriously, for the fifth time today where is the multiply() function?
Me: Wha.., it's not there?
Linker: ...No
Me: Are you sure?
Linker: YES, I AM SURE!
Me: can't be, check again.
Linker: AGHRGR
Me: Ooops, accidentally typed it as mltply().. lol
This is one of many examples as to why IDEs like Visual Studio are indispensable time savers. Typos are almost a non issue when you let go of your ego and use IntelliSense.
@@00O3O1B
Yes but then you can't run Crysis while building your projects...
*cries in the corner with a potato*
@@00O3O1B i have only 4gb ram
@@Vitriol-dk3xh Then you would have in Plasmaboo's eyes an "ancient computer"
This is the C++ explanation I've always wanted. Great series!
Same
This finally explain why we just declare things in a header file and only give one definition in cpp files, because that way the linker always find the right one when linking functions. And the #include just make that file knows the functions exist. I didn't get it since I started programming 2 years ago until now. Thank you so much.
Right? Sometimes they teach you how but not why
There's so many examples of this in programming, primarily because it's such a practical subject. Crucially, we NEED examples in order to learn how to do things and there's many different ways to achieve the same thing. I also think with the internet/Google there's the risk of 'information overload/burn'.
In the end, though, an inquisitive mind helps immensely - particularly as you are learning the language. A 'natural' programmer i.e. someone who genuinely loves programming and learning, is pretty rare (as opposed to someone doing it only for the job/money). In this channel, we appear to have that rare thing, a natural programmer. Definitely worth following.
@Fabulous Rogue At the stage of compiling main.cpp, you don't need the "definition" of Log function. But compiler will check if it has been "declared" properly (otherwise it can't generate the information that obj file need). Linker will then actually put all obj files together (of course there are more jobs to do besides this) to make the final executable so that when your Log function get called it can actually jumps to the definition part (machine code). Yes, essentially it needs function definition to run the code, but that will happen when it's at linking stage instead of at the stage of compiling each translation unit.
Can you explain what you said more simply?
@@shubhamdhingra6089 At the compilation stage all that is run is code which does not depend on any variables, as this code CAN be run before the variables are known. So, code like 5 * 2 will be simplified to 10 during the compilation stage. Any other code, which includes functions of variables, is run at run time. This run time is after the linking process. The linker knows to look for declarations of functions, as without a declaration it doesn't know what a function is and can't link it to a definition, and without a definition the program won't run after linking. After finding this declaration, it requires a definition. However, at this point, the linker has linked the files, as it has found declarations for each of the functions in each of the files, so when it looks for that definition, the definition can be in any .cpp file which was included in the linking process.
Short Summary:
After Compilation, we need to go through linking. linker finds each Symbol and Function and stitches them together to make an exe file. Multiple Obj files can’t interact with each other so if we have split our program into multiple C++ files they need a way of linking them together into a single exe file and this what essentially a Linker does.
Even if u don’t have multiple files linker still needs to link main function. It needs to know the starting point of your program. He gives example by creating a file that didn’t have the main function, this file compiled successfully however when linking it generated a linking error saying entry point not found.
There are different error types for Compilation and the linking stage in VS. It begins with C for compilation and LNK for Linker error. For example, a syntax error is a compilation error, and the main not found is a linker error.
As in project property, the config type is set to .exe file and every exe file must have an entry point we need to specify an entry point by default it is the main function. we can specify a custom entry point in linker > advanced > entry point
Then he explains about a specific type of Linker error called “Unresolved external Symbol”. This basically occurs when the linker can't find the specific symbol.
watch 6:58 can’t explain it in words. Writing static in front of a function implies that we’ll only use that function in that file only.
For the linker not only the function name is important but also the parameters and return must match 100%.
If you define the same function twice in the same file compiler will generate an error because the compiler works on one file and it can detect it. however, if you have the same function definition in multiple files the linker will generate an error because the linker doesn’t know whom to link to the call. This is the reason why we keep function declarations in .h file and not the whole definition because if we do so we can’t include that .h file in multiple files because that’ll generate linker errors.
@K k yeah but it's helpful tho.
thanks
Legend
Truly a short summary
the last paragraph of your comment is very insightful! Thanks for this!
The example with Log.h is fantastic, I had no idea such a thing could happen!
Yes
The whole series is fantastic! I wish they thought C++ this way back in my student days. Sometimes it seems like those teachers did not even know what they were talking about...
@@groberti I currently have the same issue (German school system), not even "#include " got explained at all or barely any basics to know how everything works. I'm infinitely happy to have found these videos!
@Fabulous Rogue That's the entire reason for why C++ has header files. When you include a header it's contents gets copied into the file that includes it. The when the compiler reads it it will find something like void func(int); and think "okay, this function exists". But there is nothing special about where you included it from, so if you just write the contents of the header in your cpp file the compiler won't know the difference.
@Fabulous Rogue So basically the cpp files and h files are completely separate, h files are just convenience, and through definitions you tell the compiler that something does indeed exist, but in another cpp file. So likely your problem is that you're only giving the compiler main.cpp, but you also need to give it Log.cpp
you're trying to teach all about C++ and I love it
this is the most wholesome comment on this website
he isn't only trying. you should correct it to: You're teaching all about C++ and I love it
I love that you teach the concepts through errors, as it's all good and well understanding how something works, but understanding what breaks it is far more crucial in most cases. Thank you for this series. I'm aiming to learn C++ from a Java / C# background and finding it incredibly easy to grasp the differences with your guidance. Kudos!
I used Lua and now I'm going onto C++. This is gonna be extremely challenging but thankfully I have these videos.
I totally agree, because the thing that gets frustrating when you're learning especially is suddenly running into an error like the ones he shows in this video, and then not having any clue what the problem is or how to fix it. This is honestly such a nice way to teach and to show common problems to help people who are learning.
I'm coming from a C# background and learning C++ now, I hope that now 3 years later your C++ experience has been going smoothly!
@MIKC how it going after 3 year? didyou master c++?
This guys fucking GOAT.He doesnt waste time on pointless shit,straight to the point.Plus he has a very distinc auratic music behind.Also he teaches lots of good stuff nobody mentions
everything makes so much sense now. seven videos in and this is the most excited i've ever been to learn c++
How man?
I just started learning programming 2 weeks ago, and this is by far a really great explanation (of what happens behind the C++ scene) that can be understood by a total beginner. Thank you!
@@Brad-qw1te This is the kindest RUclips comment I've received so far! Thank you so much, internet stranger! I truly got this!
btw, I am not smart. I take notes and listened to his video repeatedly for an hour or two (in.75 speed) - until I get it. I also research terms I don't understand, and have finished FreeCodeCamp's C++ tutorial. It's very overwhelming for me, but I am enjoying learning about it so far.
So thank you for your advice. I do take everything like a grain of salt, and just intake what I need to know (for now).
I'm wishing you luck too! You got this!
Linker demystified! I've been programming C++ for a while now, but this really helped. Thanks!
These videos are by far the best programming series on RUclips, I watched them a few years ago and find myself re-watching them after not touching C++ for a long time. Very well, thought out videos.
Dear Cherno, I am amazed by how you manage to give us awesome tips and tricks even when covering "simple" concepts. such as linking. You truly inspire me to dig deeper into the language, IDE, everything. Keep doing an amazing job!
This was a very well made explanation video. I'm going to recommend this to some professors maybe they'll use it in class. The only thing I didn't hear you mention, and perhaps because it's a C++ series, but linking also is when you bring in code from other languages. This is important because it's very possible to take libraries from/for other languages and use them in C++ by linking them correctly and including the proper declarations.
Now I know why they taught me to always declare functions in both .cpp & .h files
@@luisgeniole369 So maybe you got a bit confused. But I think you remember when he said that the extension in c++ files doesn't really matter. .h and.cpp are both cpp files
The fact that a professor would need a video like this to properly explain a topic is exactly why most universities are hot garbage
@@josephhooker8159 Your comment literally makes no sense. But it also comes off as if you have the IQ of about room temperature so I'm not surprised
I know why he left it out.
As he would have to address "name mangling" and as there's no standards for how names are mangled by a compiler, every compiler does it differently and it's a nightmare.
The thing to realise about the linker is that it's actually language agnostic. It deals with object files, and object files are basically the actual binary machine instructions that a compiler translates your source code into - plus other necessary bits of information about what symbols are defined and where they are in the file (so that when the linker links, it looks up these symbols and then inserts the correct addresses in the right places to physically hook up these object files together).
(Indeed, back in the day, when doing some assembly coding, I had an assembler... and then I just used the linker that came with my C compiler to do the linking. Your compiler will come with its own linker, but linkers are not tied to particular languages - object files contain the final machine instructions - and so I could "borrow" the linker with the C compiler, even though I was linking stuff that wasn't compiled by the C compiler. You can probably grab the linker that comes with some other language compiler and use it to link your C code together. Object files and linking happens AFTER everything's been translated into machine instructions. At that point, all object files are basically the same, regardless of what language they originally came from.)
The C++ compiler will take the source code and generate its object file. But, equally, if you used, say, a Pascal compiler with some Pascal source code, then it'll generate an object file out of that. The linker doesn't know what language compiler was used, it just takes object files - which is basically just the final binary machine instructions, plus some "metadata" about where everything is located, so that it can take the address of a function from one object file and then insert that address into the "call" instruction of the other module to physically link them together.
So, like, all (compiled, but not interpreted) languages end up producing object files and a linker stitches those together. And, to the linker, it doesn't know - and it's irrelevant - what language the source code the compiler translated came from.
An object file is just binary instructions and then some additional "metadata" about the symbols in that file, so that the linker knows where the functions and variables are actually stored in that binary, so that when it stitches the object files together, it can look up the symbol - such as "_main" - get its address and then hook up the "call" instruction from the C++ startup code to call your "main" function.
And, yes, you'll notice that the symbol name has an underscore. This is C's naming convention. It sticks an underscore in front of the function or variable name. Which is nice and simple, yes. You have a C function called "myAwesomeFunction"? Then, in the object file, it's symbol name will be "_myAwesomeFunction" and that's what the linker will try to hook up with other modules.
(Why add the underscore? Because this guarantees that any functions / variables defined in C source code can't conflict with other symbols. In truth, the real "entry point" in the executable is usually called "start". C / C++ will add "startup code" to the object file (this code is responsible for setting up any initialisations that need to be done before "main" runs) and then it calls "_main". That's what's really going on under the hood, but you don't have to know this - the C / C++ compiler will sort that out and add the "startup code" by default - unless you start messing around. Like folks who enter those "64K demo" competitions often play around with this stuff, because you can save many bytes by dropping the standard "startup code" and writing your own lean and mean assembly functions instead. Indeed, on modern compilers, the startup code and standard libraries included by default will often immediately break the 64KB limit that such competitions impose. So you've got to avoid this stuff or you'll have very little or no bytes left, within that 64KB limit of the competition, before you've even hit "main". I do love a good 64K demo. Watching how "extreme" coding can get, when somehow these people squeeze amazing expansive stuff into a space that many C / C++ compilers already break, just reaching "main" and doing absolutely nothing at all.)
Yes, I said "C naming convention", distinct from the C++ naming convention. That one is a bit of a nightmare topic. Because, in C++, you can have function overloading (different functions with the same name, but taking different parameters). So, to support this, symbol names get "mangled". And, yes, after you've seen what mangled C++ symbol names look like, then you can understand why the term is "mangled".
The slight problem here is that there is no C++ name mangling standard. Every compiler does it differently. It's a nightmare.
So much so, what almost always happens is that you declare things as 'extern "C"'. What this does is tell the compiler that this declaration follows the C naming convention (just add an underscore in front of the name in the source code and, no, you can't have two functions with the same name under C conventions, so you have to give that up for 'extern "C"'). Because C does have standardised naming and calling conventions defined.
So what you find is that most languages have their 'extern "C"' equivalent to define that a function / variable should be exported under C conventions and then it's easy to make things link up. C convention is just the name with an underscore in front of it. So that's the symbol name sorted. And then "_cdecl" defines the calling convention.
Anyway, you're starting to get the picture. This stuff gets complicated fast. Name mangling is a nightmare in C++. This topic is interesting, but it needs its own video - actually, possibly a series of videos - to explain and it's rightly kept out of this "introduction to how linkers work" video.
And, in practice, as I say, what usually happens is that things are declared 'extern "C"' so that they get exported following the C conventions. Because those conventions are well-defined, standardised and simple. And most language will have their 'extern "C"' equivalent and, by and large, all languages meet each other by all adhering to C conventions. Basically, because the C standards bothered to clearly define these things and it's comparatively simple. While every C++ compiler mangles names in different ways, and other languages are also like that - different compilers doing different things, making things incompatible. So the usual trick is that everyone just uses "C convention" as the "lingua franca" for interoperability. Otherwise, with every compiler of every language doing completely different things, then getting them all to meet up is a nightmare / complicated / sometimes simply impossible.
This is the best C++ series on RUclips. Incredibly enlightening. Even though I studied C++ in college and have been using it at work for the past 3 years, I often miss the nuances of the compilation and the linking process. I feel like I am in college again!
He goes a little fast towards the end so I slowed it to 0.75x speed.
Now I know what he sounds like when he is drunk.
😂🤣😂🤣😂🤣😂
Really like your videos. You have the C++ language, CS theory, practical hands on stuff like how to optimize work with VS, experience from an actual professional, low level assembly and memory, all combined with a good presentation.
In retrospect, not understanding linking errors is why I have failed to learn C++ in the past. I always had to give up with C++ from not solving the compiler and linker errors once a project got complicated. I didn't even know there was a "linking error". Your videos have fixed all that. Excellent job Cherno! Elon Musk once said that to understand the tree leaves, you must first understand the tree trunk and limbs. You have placed this concept into action by exposing us to these typically confusing errors early in the training. Thank you, thank you very much.
Great series so far! I love how people of all skill levels can take something from these tutorials.
Somehow landed back here in 2023 and this still is the best c++ series out there. People mostly want to learn c++ to get a job but neve want to know the in depth version of it's working. There is no limit to human stupidity.
@The Cherno You are awesome!!
I hope I can contribute to hazel in a couple of months!!
Doing C++ at university, and had questions like 'how does a compiler work' and 'how do you write multiple C++ files and a header and this is beautifully done. Sure, It's not directly relevent to the course, but gives a better understanding which in my opinion helps alot with standardizing code to be more professional and standard.
I feel like this series is exactly what I needed after learning the basics. There's so much more to C++ that our brains just weren't ready for back when starting.
I have been studying this series for a couple hours and realized that I've learned more than the entire c++ study in my school :)
Really good point on the usage of static keyword in header file case
Now this is what i call worth watching tutorials! You explained SO MUCH to me! Thank you! Now i understand how libraries are included like 'inline style', how and when Linker works, and that i can put whole definitions into header files (which of course is not a good practice). You make great job not only for beginners but for everyone who on some level missed some knowledge. Yours is awesome. Keep goin' and one again GREATEST THANK YOU CHERNO!!!
Wow, this series shed light in my head! As a student, I get so used to simply build an executable from a single file and didn't know anything else.
I can't thank you enough for this series, the amount of knowledge you are able to deliver in 15-20 mins about one topic is just amazing to say the least. At the starting I found it a little bit fast but now I am able to keep up with the pace.
I have been programming for 7 years now and I learned a lot from this video.
5:55 - important and also explains the use of “static”
This is a great series. I really love the way on how you are showing things practically instead of just saying it out and also giving example of error that programmers do. It really helps understand the concept well and combine them.
I am so upset when i look at the subscribes. WHy it is 100k ???? You deserve more than that !!!!! I saw gamers whose doesn't give any value for the world but hey keep watching them or giving them money. That hilarious, they make no sense. But you, you give the world what they need, you do this by your passion, you make me learn so much from you and make my coding skill better ( which is my passion too)!! So KEEP GOING BRO !!!!! I want that number to be 1 000 000 000 !!!!
this man really knows his work thank you a ton
Your way of presenting this amazing knowledge is awesome
#no blinking while linking.
Best Cpp playlist... better than many paid courses
this video changed the way i looking at the linker. i cant thank you enough
I will have to watch this one again to fully understand. Which is my goal.
Thanks for the series!
I watched this and things finally make sense. Thank you!
Personal notes for myself when reviewing video again:
- static makes that function only declared for that translational unit(the cpp file you are in), i.e. linking is only internal
- if two different files have functions with same name(signature), then you get linking error saying it has multiple definitions
king of the world, im about to have a big test on it tomorrow and thanks to you i think i can past this test.
I swear if I had these videos when I was first starting out in C++, it would have saved me manh hours of debugging code due to me just not understanding how to read linking and compiler errors properly.
Wow, amazing. Now I understand why header files are even necessary, always confused by that. Thank you.
You're tutorials are the best I've seen on RUclips, period, you explain lots of theory and go into detail.. but one huge question..... when the last time you blinked?
haha
Again, this series is demystifying so many C++ concepts and keywords. Thanks!!!!!
Dang this is the first time in my life I actually understand a c++ related explanation. Thank you!!
Really good job explaining this. Feels like i learn from 1 of your video more that 4 years of highschool. Thank you very much
Thank you so muck for covering error messages. They are one of the most important things for debugging yet there is so little explanation on them.
With the background song, I feel like watching a movie and learning at the same time. What a great tutorial series!
already I've learned more about how coding works than two of my coding classes
Rewatching this 6months later and its so helpful and makes sense
Thank you so much. This playlist is the most comprehensive C++ playlist I’ve ever come across. I’m curious if you’ve covered the topic of writing makefiles for C++ programs. If not, I would greatly appreciate it if you could teach it in the same manner as your other playlists, or provide a thorough resource for me to study. As a Computer Science student, I’ve struggled to find a complete guide to learning makefiles.
Thoroughly enjoying this.
I ran into the issue of defining a function in my header file then used the header in multiple cpp files and couldn't figure it out, thanks for that solution!
I always felt that concept of components of language processing programs I had learned were quite up in the air. really needed in-depth context on how the each components work. and i found your video and i love it so much ! thanks~~~ 😀
3 minutes into the video and i have already learned so much
You should live 100 years man!
Hands down! The best explanation on the topic.
This might be the best c++ series I've seen in a long time
Wow,it's really insane that it contains a lot thing that i never get clearly from the book,it shows that how to creat a c++ program instead of how to complete a program.It's useful for me.
I owe you buddy, yours view are underrated. You definately deserve 1 Million plus views❤
This is one of the best channel for cpp programmer
u should do these more often if u could. i really like it.
A lot of things start to make sense now!
EG how you always made a header file including nothing but the declarations during Sparky.
Great video, I really feel that this series is way better planned out than the previous ones.
I found very few people can really explain things, and you are one of the few.
You just clarified in the same video static object declaration, inline, #includes, linking and I am grateful for this :)
Wow ... that's an awesome video.
It makes the linking process totally clear (which is unfortunately skipped oftentimes in university courses)
The background music creates a soothing effect!
#include "log.h" is present in log.cpp & math.cpp,that causes linking error.
#include is also present in log.cpp & math.cpp. But why that doesn't cause any linking error?
In Log.h, the function is declared as well as defined.
I believe in , all the many functions are only declared, and the definition is elsewhere. If I "#include ", I guess I'm copying and pasting a lot of function declaration, telling the compiler that those functions exist. And the linker will find those function definitions for me.
If anyone thinks this guess is wrong, please point out.
iostream has ‘#pragma once’ compiler directive which essentially tells the compiler to include only once and if encounters other instances it just ignores.
@@spocksear7616 So did Log.h.
@@spocksear7616 This is incorrect, #pragma once only saves you from including the same file multiple times in a single translation unit. It is explained in Cherno's video on header files
Very good and explanatory. Everyone else doing tutorials go straight to coding without deep explanation. You need to understand in order to code good ;)
Could you please make a video on circular dependencies? :) I'd like to understand them better, to be able to avoid them.
You're doing a remarquable job, please just never stop!
This series we needed, but didn't deserve.
Good vid btw, I hope when this serie is finished that it will make it a lot easier for learners to understand all these processes.
3:45 In embedded systems, usually the reset handler is the entry point.
"Now you might think this kind of error doesn't happen often and you're smarter than that"
My famous last words before I started coding and getting to know Dunning-Kruger ^^
Nice series btw
As a newbie in game development I would like thank you for your lessons. They are simple and full of knowledge. Cheers!
Best explanation in my 25 years of programming
Awesome videos dude, ive been going through your C++ playlist because i just got moved onto a C++ team at work. thank you!
You are the real master in the field of c++😃
Wow, you just made the keyword static make so much sense to me now!
all 15 min without boring. You are great.
it is a shame for me because I found this channel so late and it is a shame for you there is no education for c# like you did for c++. great tuts. thanks
9:42 healthy blinked 👍🏻
great. I felt very hard when I encountered these problems. Now I can know properly about them. greatt.
Great work, man. I like how focused these videos are. Gonna binge watch this series, then I'm 100% on-board for the Game Engine playlist. Keep it up!
Your tutorials are the best I have found online. Very helpful for my Uni course.
Great series Cherno! The very best in fact! So easy to understand what you say, very precise and to the point and full of facts. Love it.
This is an extraordinarily good video! I love how you managed to blend together the basic concepts and faults behind error with more practical examples of how they may happen in the wild. Great job!
Please provide a index for your tutrial so that i can watch videos when you will be over with basics. by the way your teaching skills are best
I am translating a code from Fortran to C++. This series is so useful, thank you Cherno!
Yet another wonderful tutorial by Cherno. Best video I have ever seen on this topic. Clear, concise and full with enlightening information. Congratulation!
amazing work !!! after near 2 years of coding experience in c(uni experience) finally i can understand linking and compilation . Thank you ! you explained this well and much better than in Academy course's for Shure
I have never appreciated C++ that much. I am in love
Best C++ channel ever!
Awesome video as usual! You've made c++ compilation so digestible with this and the compiler video. Thanks so much!
hope these would come out faster beacause they're prettty good!
So afar what i understand after two c++ tutorial...is simply because in c++ after compiling all files will get combined in one file and double declaration (#include) of same thing means you are defining twice same object/function. different than javascript where double declaration gets replaced with the last one. pretty much standard so far.
Bro. I'm loving your series! Thank you for being so comprehensive and detailed.
At 14:31 we are including the log.h file which calls the log function, but since there is only one definition of log function in the whole project there is no error.
No the log.h is only declare it .
It doesn't call it
can u do a series on Linux stuff and one on Architecture including assembly code? you know a lot about low level stuff which is especially confusing to most cs learners. great channel!