"In the beginning you always want the results. In the end all you want is control." These two lines more or less sum up my 10 years of programming experience.
@@dancom6030 It's over 40 years ago, I got my first computer born with BBC Basic and inline assembler. One second to boot and no noise. So back then, I learned hexadecimal and 6502 assembler. I could even have met Dennis in the discotheque in the seventies and having beers together, but I did not know English either. :o)
0:00 intro 5:00 garbage collection is not suitable for high performance scenarios 6:20 prefer stable & concise language features & technology stack 8:25 avoid ambiguity 11:00 don't be "clever" 11:45 be explicit 14:40 static-type language can catch more errors 16:00 early crashes are better than hidden bugs 17:30 improve your developing tools 20:20 general naming convention & coding style 27:20 prefer imperative & sequential code, long functions are OK 31:40 function naming 35:20 API design 36:00 how to organize .h & .c files 38:40 C & OOP-style APIs 41:00 void pointer is your friend to hide internal data 44:18 macros: __FILE__, __LINE__ 49:40 a custom allocator for memory debugging 53:10 macro utilities for binary data packing/unpacking 57:10 memory control & pointers 1:03:00 malloc 1:06:00 arrays 1:09:20 struct 1:11:15 inheritance via C pointer casting 1:16:35 struct packing, padding, memory alignment 1:22:55 memory pages, realloc, gflags.exe 1:33:42 memory caches 1:42:30 don't store data twice 1:45:25 trick to reduce allocations: Flexible Array Member 1:48:30 trick to reduce allocations: joint malloc (dangerous) 1:50:48 use "stride" for better handling of Array Of Struct (AOS) 1:53:15 architecture on top of small & flexible primitives 1:55:45 prefer incremental progress 2:00:00 fix code ASAP 2:01:55 UI application design 2:08:50 Carmack's fast square root algorithm 2:09:56 magical random number generator 2:10:30 closing, contacts
Nit: fast sqrt isn't Carmack's. From Wikipedia: > The algorithm was often misattributed to John Carmack, but in fact the code is based on an unpublished paper by William Kahan and K.C. Ng circulated in May 1986. The original constant was produced from a collaboration between Cleve Moler and Gregory Walsh, while they worked for Ardent Computing in the late 1980s.
He has a point about 5:00, the biggest optimization you tend to do in GC languages aside from improving the algorithm is minimizing allocations to reduce garbage. Languages like C#, Java, and Go are massively improving their performance stories. I can really only speak on C# as I’ve been following the changes. Access to CPU instrinsics, stackalloc, no copy slicing, Ahead of time compilation, These languages have gotten much better in that area, they can definitely reach really high throughput, where the GC can trip you up is in latency sensitive scenarios. Also runtime reflection.. it’s used a bit too willingly by libraries. I think these days if I really wanted to write in a systems language like C, with a batteries included Stdlib, and explicit control over memory I’d probably use something like Zig. Keep the core language simple, use type inference, treat types as first class so the language should have the ability to modify types and run expressions at compile time. Pretty much don’t use macros let type system be expressive enough to do what macros do so everything is type safe.
As a beginner I can't explain how much I appreciate this video. Clear, concise and simplified without sacrificing content. I started with python and am struggling with picking up C. Learning syntax is one thing, learning HOW to apply it is another
"the compiler is your friend when it tells you something is wrong." This is very true, but the problem with that is that C compilers give the least detailed or useful error messages out of any language I use, not to mention that managed languages give you actual error info at runtime instead of just "segmentation fault." Edited for clarity.
anyway i mostly agree with the stuff in this video but i think the takeaways can be applied to non-garbage-collected languages that are much better than C
“if you’re gonna be a good programmer, you’re gonna want to learn how to do things” ugh exactly!!!!!! there’s so many phenomenal points in this presentation - Although there was a LOT of typos in it 😂 no judgement though
Thank you for this. I wish there was more of this kind of content available, but nowadays it's full of "Learn X in 2 hours", "How to make a CLI tool in X", etc. This was something I watched closely and took notes.
Awesome, people can dislike, trash all they want but, how many videos like this you see out here? You wanna watch a video on how pointers work? Linked lists? This is real life code and it's awesome that someone took the time to do a video like this. Congrats, man!
UA-cam recommended this again after a year and I it think this is gonna be one of those videos I come back to every year to pick up new info and see how my C understanding improves
1:42:00 - If you already know the index to remove, you can just use memmove. It's much faster than most people realize because it will invoke SIMD operations and hardware intrinsics to move multiple chunks of memory per cycle. It can actually be faster to memmove an array to remove an element than to remove an element from a linked list using pointer reassignment. Pointers can make things very slow if they aren't used correctly.
Started my journey of learning C++ 6 months ago from 0 experience in programming, just watched 16 minutes of your video for the moment but you're already saying "philosophical approach" stuffs I instantly felt during my very young journey. Very glad to hear my noob "feelings" are not that "heretic" : "why overloading if I could just type few more lines ? why hiding me some details of the code and optimize things I could do myself , getting me bad habits ?" ( especially when learning the roots of how everything work, it's hard to connect the dots lol ) Thanks from a rookie, to help me open my mind in this world :)
Read up on dependency inversion, thats the #1 biggest thing that makes for clean code. It is the god all mighty of abstraction and code simplification.
something can be bad, but still be useful anyway regardles. but i get what you mean and feel, that was my first impression for a few minutes as well :D
I'm an intermediate C programmer, and this video was very very helpful and very well put together. Thank you. I wish I saw this immediately after taking a C course!
I'm a Julia programmer (started with C and C++) and I love watching videos on lower level languages like C/C++ and Rust and always appreciate the level of control you can get over your memory. I love the framing of "Not wanting to manually manage memory but then living in fear of the garbage collector" I think the reason why people fear the garbage collector is because they don't understand how it works, and then they make mistakes which worsen the impacts of it. In Julia's documentation there are dedicated sections to the internals of the GC and how to optimize your code so that your code can work in tandem with it. I've had so many situations where simply tweaking my code according to those guidelines resulted in ~4x speedups and ~3x less garbage collection. No matter the language, try to learn it inside out to the point where writing optimized code doesn't even require thinking about it.
That adds to his point though, the time spent researching and understanding how to work around your languages garbage collector is time that could have been spent learning how to manage memory instead.
Take it with a huge grain of salt. There's a reason why many "new" features have been built to newer versions. This code you are looking at is very outdated. Like, why name something module_object_action when you could use namespaces which is made exactly for that cause (module::object.action). I'd look elsewhere. He also advocates monster functions which is just horrible and completely unmaintainable and unscalable way to code.
@@QckSGaming problem with namespace comes when you're in a shared project with multiple programmers. It gets confusing real fast. In standard libraries yeah it's fine nobody will confuse 'cout', but other than that yeah.....
@@uziboozy4540 old stuff != bad and vice versa, plus everyone have their preference. If you like rust more power to you. People need to try out new stuff especially in tech field. But disregarding something just due to its age is bad mindset.
@CooCooWizard overrated? Whether or not you think the syntax is garbage, is just your own sensitive opinion. To me it just sounds like you're either too stupid or too lazy to learn the language. If you don't like it, don't use it. Rust is still better than C or C++ without doubt. Please, elaborate on anything that is better in C/C++ as opposed to in Rust. I'm not a fan of the way implementation works in Rust, so that's a win for C++ there with classes. Other than that.. nothing
I would really love to see a whole C tutorial. I have been searching someone like you, who can really teach C. Please, I really insist you to make aa whole tutorial series for C. I am a new CS student. And I absolutely love C. I also want to do some networking, system programming. You tutorials will help me a lot and others too. Please make a series.
Don't think you should learn C by following tutorials, it's really a terrible idea, and I speak from personal experience. You become a much better programmer by doing your own projects that you care about, from scratch and try to figure out things as you go, looking up certain things a long the way if you get stuck. Getting stuck in tutorial hell will get you nowhere. Just many hours of videos watched when you could have been making stuff and honing your skills. That being said, C is an amazing language. I come from a C# and JS background and I fell in love with C once I decided to learn it properly. It's so pure in a way, I find that I can focus a lot more of my time of figuring out how to implement functionality in my code rather than worrying about abstractions and things not related to what I'm actually trying to do. Good luck!
@@apresthus87 What you just said, I did that exactly the same way. I wrote that comment 5 months ago. I already learnt C and C++ then. But I wanted to know more From experienced programmers. I did small and also big projects with C and C++. I love lower level things so much, that after 1 and a half year I am still using C and C++. Learning new things, trying frameworks, graphics library etc. I just wanted to know more, thats why I wrote that comment.
@@raihankhan197 That's good to hear! My answer was just as much for beginners that stumble over videos like this. Many beginners get tricked into thinking you can become a good programmer by watching tutorials. I used to be one of them :D I wanted to see how experienced programmers structured the code as I went on instinct more so than anything when making my game engine as my first big C project. I'm happy to hear that you are doing well and still using C though! :)
This is literally one of the best advanced programming talks on UA-cam. 30 years of experience programming and so many "hey that's brilliant moments". Thank you for making this. (You gotta spell check your code comments more though. yeesh!)
@@Julian-mc3tc that's bullshit bruh. also this talk is kinda trash and culty and is literally anti-intellectual. Science and technology is built on top of common trust and sharing. him trying to prove he is a genius after literally saying don't be clever. watch jacob sorber or molly rocket :: handmade hero if you actually like building stuff with C. There is also this guy who builds like tiny 8 bit pcs from scratch which is pretty cool.
the inverse square root works because if you bitcast a floating point to an int you get a decent approximation to the log2 of the number in fixed point. Then it uses the fact that log2(x)/ 2 (where the bit shift comes into play) equal to log2(sqrt(x)) and a bit more math™ to get a good approximation of the sqrt which is then refined using 1 or 2 newton-raphson iterations.
@@ekrem_dincel there are several explanations for this on the web. It was popularised due to the source code reveal of quake III, so the algorithm is quite well-known. (Apologies if he said this in the video. I haven't watched that far yet.)
The inheritance using casting absolutely blew my mind. I have a project with a similiar inheritance sturcture and i never thought to do that. Definitely saving this video!
I would prefer a Swedish programmer that do a few spellings errors which the compiler will handle, before a Norwegian fish farming guy with an IQ slightly under the salmon's.
This has some really good points. In my (admittedly somewhat limited) experience c++ is good/ fine if and only if you are disciplined about the abstractions you create. For whatever problem you are trying to solve, think carefully about what abstractions will make solving the problem easier then implement them, including operator overloading, and then STOP. The rest of the time, build the solution out of those early abstractions and don't introduce new ones unless there's a VERY good reason for it. Then you get the best of both worlds. It doesn't make sense to have to write loops to add two vectors. "+" works perfectly IF you are disciplined about it. That's why c programming experience is vital for good c++ programmers. Coming at c++ from python without c experience will transfer the "wanting results" to c++ code instead of "wanting control" as the video says. Good points, just not quite so absolute.
Agree about C++ being good and having the discipline to not over-engineer your code. I think that can be applied to any language - when I used to write Java and I was still relatively new, I had a habit of getting carried away with class hierarchies and abstractions. At the end of the day the abstractions were mostly useless, and they overshadowed the actual code that solved the problem. Nowadays I do a lot of C++ and I've learned a lot since then. One of the most important lessons was to just build the damn application. You don't need class hierarchies unless you have a very good reason for them, and you shouldn't introduce extra abstractions until you have a clear need for them. Having to refactor some code is not the end of the world.
This is fantastic. So much experience condensed into an easily digestible format. Thank you for sharing! Having a bit of (theoretical) background in C and C++, just from reading mostly, I've always been hesitant to work in C. Most of that hesitation comes from what I learned in school about OOP and all the do's and don'ts. I've already started doubting much of that since, I always felt it made programming so much harder than it had to be and your video just gave me that extra push.
The best thing about C is that it IS actually a very simple and elegant Programming Language and you still get full control of your HW with it. I never understood why so many people hate it so much. As you are pointing out at the beginning, I actually love it for all the reasons other people hate it. Thanks for this very good talk!
Franz Flasch No, in fact NO. I love C, but even this tutorial is full of undefined behaviour (WHICH is really dangerous) and bad C practices. Do not cast pointers, do not cast structs even when they are identical. Do not ... C is full of DO NOT´s which you really must avoid doing.
22 minutes in, and this is totally my speed right now. This is where I’m at on my journey in learning to use C, and it feels so validating to finally come across something like this. Looking forward to the rest of the video. Thanks for sharing. ☺️
I will be honest, at first I did not like this video too much. However I kept watching until the end and now I think I really like it. I think the parts about why C is the best language and other programming languages aren’t so great could be left out. I really like the deeper knowledge that this video provides. I think this video is not just a great video about C, but rather a great video about computers, programming, and memory through C. Thank you for sharing
12:15 Not a compelling argument at all in my opinion. Operator overloading mostly makes sense when it's used to define real mathematical operators. (With the exception of string concatenation i guess, and maybe other types) Operators *ARE* functions. They take data in, they spit data out. If you're smart enough to understand that "strcat" concatenate two strings together, you're smart enough to understand that '+' concatenate two strings together. Its just another notation to mean the exact same thing. Using the example of vector multiplication is dishonnest : its ambiguous because there's no clear definition of what a multiplication of vector is. Not because '*' is not explicit in and of itself. And that's why half the people say parwaise mult, and the other half say dot product : They don't know because there's no good anwser. In fact, i'd like for you to elaborate on why you think "mult_vec (&vecA, vecB, vecC)" is somewhat more explicit than "vecA = vecB*vecC". there's no sementic difference between them... they mean the *exact* same thing. They're Just written differently. Therefore if "mult_vec" is explicit, so is '*'. I suppose you *DO* use operators on primitive data types ? Why ? Why are they explicit enough ? Because you know what '+', '-', '*', '/', '%' mean on numbers. In reality, no operator is explicit. You **HAVE** to know what they do to know what to expect from them. If I'm able to know what an operator does to primitive data types, I don't see why I wouldn't be able to do the same for other data types.
You clearly missed the point. What an operator does to primitive data-types is clearly and unambiguously defined by the standard. It is guaranteed to remain the same forever, irrespective of the compiler and much less of the person writing the code. With overloading, it is up to whims and fancies of whoever implemented it. mult_vec (&vecA, vecB, vecC) clearly advertises itself to be a function call, the documentation of which can be looked up. B*C looks like a standard operation when it could be, sans any type info, literally anything. To make matters worse there could be 100 different overloads of the same '*' operator even for the same type for different second arguments types. My biggest pain when debugging C++ code is that there is no quick way of finding the correct overload or template specialization that is being invoked.
I agree mostly. It's really a problem of having a feature that risks ambiguity. In C you'll know what uint + uint is assuming basic algebra knowledge (and overflow knowledge). For many it may be unintuitive what uint* + uint does. But the reason that isn't a problem is because it's well known to someone who knows the rules of the language. People can agree that someone who doesn't know the fundamental rules of the language don't count and I think most do. You wouldn't criticize a language because a newbie doesn't get it. They're taken out of the legitimate confusion set. And you need that boundary somewhere. For operator overloading it's not going to be consistent everywhere. I can't hold you to a standard where you have to intuit what every library author chose their vec*vec to mean. It's a risk averse approach. Not trying to absolutely eliminate confusion. I'm not personally all that opposed operator overloading. If that's the only interface for types I don't approve of I wrap it. I use it for vector types sometimes. You really just have to check that you know what the operators do before you use them.
I think theres an even better argument IMHO. You can create your own operators to avoid ambiguity. They're not exactly operators but the resulting code will look as if they were. stackoverflow.com/a/41780190/7322371 Im guessing the author of the video would hate that solution but in that way we can have both multiplications : vecA vecB , and vecA*vecB, and at this point its obvious which operation we're performing.
@@lupsik1 That is not creating a new operator. It is simply using a (very ugly) hack that overloads the '' operators to make something that looks like a new operator while relying on not one by two operator overloads in the background, not to mention the additional overhead due to the template being used. But that is not even the real problem. There is a reason why C++ only allows existing operators to be overloaded. If a program is filled with multiple such custom 'operators' does it decrease ambiguity or increase it? Imagine trying to debug someone else's code where he has gone wild with those! Your link serves as an even better example of what is wrong with operator overloading. This is the kind of horror that sub-standard programmers create using the features that C++ provides. This is exactly what Linus was talking about in his famous anti-C++ rant. He wasn't against C++, he was against the large number of C++ programmers who don't understand how to write simple, performant, readable, debugable code. The worst part is that these guys don't even understand what they are doing wrong - they think it is cool!
Hello, I just came across your channel and I'm glad I did. I'm new to programming, the paradigm that most people on youtube teach when talking about programming never has resonated with me. I just don't learn that way. My mind can't think abstractly enough to understand some of the stuff they talk about. I understand things more literally. I've been trying to find resources for quite some time now that would help me get my foot in the door for programming. I've been through the trenches of tutorial hell with several language. From what I've gathered from your lecture is that C can abstract things if you build your program to do so, but it also seems very explicit. Maybe I'm wrong on that. I come from a hardware background, was in the Navy for a long time and have a deep understand of electronics and digital electronics like TTL and IC. I've always wanted to get into programming, mainly because I've always wanted to make a badass game, that was mine. Is there any resources you could share that could help me get started on this journey? Maybe ways to think about the tremendous amounts of mathematical understanding you need to do something like you did with building a graphics rendering in scratch? I think I've made up my mind though, C seems to be the language for me. It's closer to machine code then anything else I've seen, save ASM.
I love this talk a lot. Watched it a year or two ago when I was starting out moving over to c from c++. Just re-watched it after actually getting into a c opengl project pretty good. Got a lot more out of it this time. I really agree with your philosophy and found myself doing a few of these "wrong". Gonna incorporate some of these tips. Cache friendly main loop is still eluding me. Thanks for all the sharing you do.
1. About function overloading, I do actually prefer c++ here, as it has a way to specify the type, and be less cryptic about it. It's literals for when that is available or explicitly calling type constructors when not. There is an argument as this is not enforced and implicit type conversions may cause a bug, but when you need it, providing argument type with the arguments themselves, instead of in the function name will force you to change them once you want to edit the function call. As a benefit, you also get arguments types as part of function signature which helps a lot with naming, as while it is good to be explicit, and not have ambiguity, going too much in that direction will lead to code becoming white noise, and it's much harder to not make mistakes, or miss anything while reading. 2. I agree crashes are good, but to me it's obvious that compile time errors are strictly better. Love the video otherwise
Agree. In general I think any language feature that forces typings from the syntax into the naming tokens (in this case method names) is a bad one. This usually devolves into having to maintain some kind of consistent notation to encode the type into the name in the interface (like Hungarian notation), and quickly becomes unruly. This is also a case where a compiler could easily warn that one of the arguments is being downcast or whatever in the given example
"Typing is not a problem" But reading what you typed is. You need to read this multiple times and that takes your time. And the more time you spend on reading abd understanding the more time you lose on other tasks. We kinfa don't have 3 years to write server for our project, cause during that time it would be outdated enough.
@@TheExiledMeriler See the guys homepage. I think this is some form of learning disorder or so. As you hear, can he speak just fine, so it'ss not about his native origin or so. I know for a fact, that there are disabilities who prevent consistent and correct spelling. That does not impact your ability as programmer, obviously
Excellent talk. Especially for the garbage collection i love C and C++ This is so crisp and clear explanation: hope you will make more videos like this
First half is just "language X does Y which sounds really nice until Z" except you basically never experience Z and Y is absolutely amazing and makes you code faster
@@eskilsteenberg en.wikipedia.org/wiki/Programming_languages_used_in_most_popular_websites C is 5%, you think they'd catch on? Not to mention the percent of high severity security bugs related to memory problems
All of this information is excellent. Anyone writing code should strive to understand all of these concepts no matter what language is being used. This video may be a bit older, but it is still very relevant. Thank you for posting this wonderful content.
The video description needs to be corrected. This is not programming religion, this is programming philosophy, and damn good philosophizing at that. I've learned so much within these 2 hours of watching.
Wow. I am an undergraduate in comp sci, and oh my goodness… this video opened my eyes to concepts I once thought difficult, but now I have a lot more clarity on them. This was an amazing video
Whenever I saw the thumbnail with "extren" typo I thought this was a comedy video, like the guy that jokingly uses MS Word as a text editor for coding. But finally clicked on it and realized it's a serious video; and it's good, thanks
What a great video! Hope more people will be "enlightened" and discover C 's elegance in simplicity. And for those for whom some of the shortcomings of C would be a deal breaker, I'd suggest looking into Zig. It aims to be "a better C" by doing away with the most "problematic" features and adding some that really should have been there, while still remaining low-level and explicit
@@xydez I'm gonna have to try Zig now. Rust is almost entirely unreadable to me, just like C++, so if Zig is really that bad, i'm gonna have to stick with Go.
@@epsi the really good thing about rust is enums, they make life a lot easier. Still id suggest you give it a try, its a very nice language once you get the syntax
@@epsi C++ hits the balance just right imo, and it fits in with what he says at the start about how at first you want something to work but later on find yourself wanting extra tools/control that you can't add retroactively. You can still write that simple C (only major difference is you have to cast to void* explicitly) as much as you like, but when you find that situation where templates will save you hundreds to thousands of lines of code, or where using a class and some overloads lets you just wrap your brain around a problem by just raising the level of abstraction - they're there for you to use. Or you can shoot yourself in the face with them if you're so inclined
Zig being a better C is almost the same lie told by C++ inventors to make the new language get adopters because they can't make something better than C, the temptation of doing clever stuff is just too much. Zig does have some good points, but it is almost as complicated as rust and c++, and it has some insane stuff like unused variables stop the compiler from processing your code.
Totally agree with all your points. I have a tendency of building everything from scratch but I get demotivated by anyone who hears this (generally). Highly motivated after this ❤
Really cool stuff! I just started writing C, for fun I guess, after years of node.js and before that PHP. I love how simple it is! Everyone talks about the big scary memory management thing, but once I could visualize it, it makes a lot of sense. I’m going to have to rethink something I’m doing with doubly linked lists now, but the ideas of structs having a definite size and structure that’s usable, as well as the ideas of stride and “inheritance” makes something else that was going to become a quadruply linked list much easier and simpler I think! (I have to reason it out still, but this potentially makes my life a lot easier!) Also I love the debugging stuff with macros! Truly ingenious! So far I’ve just been using them to colorize printf output by prepending escape codes automatically xD Sorry for the long comment, but the video contained a lot of gold info to comment on as well!
I'm in the same boat, long time JavaScript dev and I'm starting to code in C for fun in my spare time. The simplicity of the language is just so cool. I don't need to Google around for different frameworks that I need, I can just write them myself!
@@christianbouwense4702 Have learned since I wrote that, that how I think is the best way to write something is often not very efficient in terms of code lines or memory/processor use, but that's learning xD Strings though... zomg. strtok is actually destructive and will litter your original string with NULLs. If you need to parse things but still need the original string, keep that in mind. You can create your own that uses a string buffer and string views (which track the starting and ending point in a struct rather than using null terminators, but keep in mind to convert it back to a string for any functions that require nul terminators or else implement string-view aware versions :)
@@jmrumble Nice, thanks for the info! Yeah I'm still trying to get used to strings and arrays in general. One thing I'm trying to wrap my head around is: if you have a function that takes in an array, is it standard practice to always pass in the array size? Is there any time you can omit the size? And if not, what about strings? 🤔 Should you never assume they're null terminated in a function body?
I learnt why C is superior to all. I only know Python and JS front-end framework. Learning C is a fight worth fighting. Thanks this is an eye opener for eveyone.
I'm only 16 minutes in but it looks like I agree with you. I have lost days because something didn't throw an error when it really should have. I have noticed that clever critiques of programming languages are often used to flex. But in your case, I think you are just thinking for yourself.
@@stewartzayat7526 except it doesn't. in the same way it was the guy's decision to encapsulate that macro, it also was his decision to do the same with the operator overloading example
Dude this is how teaching should be. I been really trying to innerstand the concept of what code is doing and why numbers are needed. Why why why. Thank you man ❤
23:32 On this point, most IDEs or even text editors have a "match whole word" option when searching, which looks for word boundaries when searching. This removes the issue of searching "my_function" and getting "my_function_with_stuff" and also works for other types like variables.
recently I've been trying to do some bigger projects and i can affirm that without this video as a reference i would reach insanity before having a functioning build
I started with C and then went to Python. I actually felt uneasy with Python right away because it felt like I had no idea what was going on half the time and stuff was happening by magic. 😅
The most underrated nugget of wisdom is "build a mountain." Everyone thinks those of us that write C code constantly reinvent the wheel or start from scratch. Most of us have been building a mountain for years that all future work just builds upon. It takes awhile to build but once you do, it's yours and you wrote it so your productivity is enormous. You can then focus on debugging your code instead of debugging your knowledge of the language as I find myself doing with languages with ready built mountains like C++ and Rust. It's why I am interested in Zig as their philosophy seems to be in line with this idea of keeping the language simple but slightly higher level of abstraction.
@@MrAbrazildo Well, this is the debate. OO tends to reduct the total lines of code, but increase the lines of code you have to view when you debug per issue. When you look at the code that triggered the bug, it's hard to tell what is local and what was inherited, patched, subclassed etc.
@@jayflaherty5260 In C++ you can name a list of 'friend's, which says who can access specif data. To breach that security, a bug has to be nasty, usually combining more than 1 error. And it's possible to craft tools behind operators or classes, which can debug without changing the external code.
This video made me realize how C can be superior to every other language, great work. I'm glad I live in a time where this content is readily accessible.
C is constantly present but not exactly everybody knows/cares about its effect on programming. Being the first significantly high level language, its basically the source of how most programming works today
But it isnt exactly the best language for everything. People like to mention webdev against C as an example but almost anything that needs hardware knowledge is c required
Thank you so much Eskil. Thank you for sharing both; your knowledge and your style. Now everyone can see that the output is just a reflex of the input, meaning that your software are beautiful because the way you think about how to write it, is beautiful. There is a large amount of advice and details here that is very difficult to find out alone if you are a beginner. Gold in the form of a video.
Immediate like for "C is the greatest language." Totally 100% agree: I love every feature about C including its limitations. It makes it more elegant, in my opinion: one thing is for sure, I always know exactly what happening (like near the metal) when using C. Or, if I don't, I know that it's completely my fault and not the fault of language weirdness. Everything it does is because I told it to do so.
I do agree with you about the explicitness of C, and you build whatever higher abstractions and libraries that you want to build -- low to high, and full control.
@@avashurov that's not an issue though, it's not a good idea to ever use "int" or "long", use standard integer types which are guaranteed to have a specific amount of bits
I agree with everything. I always thought you should have control over memory. People make it sound like this scary thing, wow pointers! memory! so hard! I honestly realised how simple was memory while working with binary files. It's pretty much the same except certain sizes are padded to be properly aligned. Plus I wasn't even working with binary files in C but its so related that the realisation hit me in the moment.
You are absolutely correct. C is the only language that i tried which does exactly what i want it to do and not anything more. That's why i love using it, i can just look at c code and tell what it will really do and how the code will compile. It is also a great language as it has no abstraction of the most basic tasks and you have to do them yourself instead of relying on the compiler. Other recent languages are good if you just want something done effortlessly but if you're a programmer or engineer i see no other reason to not use C. The language itself can teach you more about computers and hardware by making you do everything yourself.
C is great for learning and hobby projects but there are real reasons not to use C in production software. The lack of a standard library means that you'll probably be implementing basic data structures yourself in your own quirky way (do we use void pointers? do we use macros to simulate specialization? etc.) The rest of the team will then have to learn your way of doing simple things. And that goes for everything in C - it seems like everyone who does C has their own style and their own convention. That's all overhead that other team members will have to learn to contribute to a C project. Other reasons not to use C for production: - Spending time implementing basic data structures and algorithms (that should be part of any other standard library) takes time away from building the actual product - Your custom data structures are much more likely to have bugs or be less efficient than battle-tested ones - You could use C++ instead and have language conventions and a standard library - plus most of the features from C
Is your approach that because C++ has features that are easy to misuse you should just not use *any* of the features provided? the add() example would, for example, be an amazing candidate for templates, notice how that would be better, not worse. With regard to the multiplication example in C++, write better code! Someone writing ambiguous code is not a good argument for not using an entire language, it's an argument for better education. I don't think we should use C over C++ just because it has less features. C has it's place, but I don't think it's the same place as C++'s.
Just use selected features of C++ in your C code, and use a C++ compiler. You don't have to use all the features of C++, only use the ones that you want. Any good C++ compiler will accept valid C code.
It's quite frustrating how fan boyish people get. There are useful features to both languages and both features can be abused easily enough. *cough* macros *cough*
I was thinking the same thing. I've heard the "easy to abuse" argument for operator overloading many times, but the problem is that people make intentionally misleading examples. I've written enough Java that I hate writing .add(...) when I really just want a +. That's exactly the time to use operator overloading, not to confuse things.
I as a C++ programmer kind of disagree with you and agree with his perspective. While I personally think using a C++ compiler with select features is the way to go, his overall argument seems to be that writing C code *forces* you to write good, rigorous, "non-clouded" code. Yes, with good programming practices and standards you will theoretically will never misuse any of the features provided, but to me it seems that isn't how it often happens in practice, with many libraries going down a completely unmanageable path because C++ made it easy for them. Again this is just how I see it, but I am a C++ programmer and love the language, so I don't really have a bias in the C direction when it comes to this
this is all fine and dandy until you actually have to cooperate with someone in c++ and you disagree about what's the good minimum subset. Now you don't even know the same programming language as other c++ programmers, and cannot cooperate. Well you can cooperate; just not in c++, but rather in the subset of c++ nearly everybody who programs in it knows/uses: c.
Content with very skilled competence. After 18 month of C++ and writing two relation databases and tons of training code, I realize, that C must be the future for me. I’m hoping Eskil is making more talks about C. It’s is gold and super interesting. The parts with structs, pointers and memory management is fantastic and explained very well!
Another thing I have picked up from this video: long functions. I have always been taught to “abstract away” and “encapsulate” things and then it becomes an easter egg hunt to find the function within the function within the function! Having however One loop like you suggest that simply does things based on conditions/state and is very clear about that and reads top down like a story book is Sooooo much easier to read when coming back to later. The problem though is that though I like it, other people don’t…
I absolutely wholeheartely disagree to the biggest extend. The analogy of a story book reading from front to back is sorry to say stupid. If you have a problem with your electric utensils do you want a manual with chapters and subchapters or a block of 200 pages starting in chinese? Finding a bug is not a story, its a specific line. Imagen this scenario. You have a 2D Game with a gigantic draw loop of 1000 lines of code. Lets say the drawing of one particular scenario has a bug. Do you want to a) read through 1000 lines of code, skimming over it ofc, but still 500 lines average. or b) Follow down a tree of smaller and smaller boxes to zoom down to your scenario? Your IDE is happy to help. One you skim over 500 lines, where the other you read and think about 10 lines of function names. Not convinced? You still have 1000 lines of code and the bug is super hard to find. Have fun testing one function of 1000 lines of code. Imagen the stacktrace. Bug happened at line 643 of function x. Instead of: Bug happed at line 13 of function x, called by function y, called by function a called by function f. Which for my example would be something like: DrawDoomEyeMonster , DrawFlyingMonster, DrawEnemies, DrawGame, Draw Another point, if someone is a bad programmer the difference between the one line someone hid by accident, is either 20 or 999 lines away. Whoever says big functions are easier to read is lying or super bad at naming functions. --- However every rule has its exceptions. If there is no reasonable way to split code, dont. Make sure every function is free of side effects.
@@Schnorzel1337I disagree, strongly. A better example would be a malfunctioning drill that you need to repair. You open it up and troubleshoot the energy lines linearly from the power supply to the end tip. The simpler and the more straightforward the design of the drill, the easier to find where a broken trace or burned component may be. But if the drill has a bunch of smaller different units jumping off from each other it becomes increasingly difficult to see where the energy may flow and it becomes much more time consuming to find where the problem starts A procedural program is executed from start to end. A bug may start anywhere in that line and make itself manifest anywhere else beyond that point. Tracing that problem back is relatively easy of you have a straightforward block of code to step through. But if you have a backtrace of dozens of functions, tracking where it may start is much, much more time consuming. Especially for something like c, where silent but killer pointer bugs are everywhere I recommend checking out an article by John Carmack on inlined code (you can google it), he is a lot more terse in explaining why it's a good idea
Can you explain what you mean by that? I'm guessing you mean you write/compile in C++ but you tend to use the base of C with very few pieces of C++ used on a "as needed" kind of basis?
@@jmullentech For example, If I need a priority queue (I am a competitive programmer), I use the one from stl. I compile as c++, but I use raw arrays and memset instead of vectors when I dont need extra vector features such as dynamic memory, etc. When a c++ feature makes life easier, I will use it instead. for example, memset is only for same-byte fill. If I want to fill an array of integers to a value like 1337, memset cant really do that, I use std::fill_n (c++ feature) instead. Stacks, Queues, Sets, etc are really user friendly and implementing them, especially in time limited senarios and competitios is kinda pointless I believe for every field in C/C++ usages, there exists a right balance between C/C++. In competitive programming for example, stl saves you a crap ton of time. I rushed this explanation since it's 11 PM my time, if ya have any questions hit me up, lior5654#1856 (discord)
@@SaidMetiche-qy9hb I know, that's the whole point. Re-read the sentence. C is usable within c++, C+ is writing c-style with specific c++ features. Memset in an example of a C featute
Love this! The object-oriented part is _very_ good. Not taught at CS programs at university, at least in my case. Sad thing is that novice programmers coming from Java will think pretty much everything said in the video is wrong and bad "design".
well, it is bad design. I'm not a novice programmer and I know a lot more than java but this is objectively terrible design. software today is developed by teams who need to be able to read and understand each other's code. modern languages like C++ make this easy for you by providing standard language features to structure your code in a sensible way. the way this guy writes C is his own personal style, not a standard, which means that you need a 2 hour talk to understand it. he also prefers to write tools himself because he doesn't trust libraries (even though said libraries are mature according to him). if every programmer had this piss poor attitude, then nothing important would ever get done. it's just arrogant to expect other programmers to read your code and learn the way you do it when you can't be bothered to learn a library and see how a better programmer does it. it's doubly arrogant to then give a talk on your ass way of writing code as if you're enlightening all the morons who would have been lost without you.
@harleyspeedthrust4013 you are mega retarded. C++ gives you at least half a dozen ways on initialising an int. half a fucking dozen. And you want talk about standardisation. Pull your head our of your ass you dickhead
I think I still prefer C++ although you make some good points that I agree with. C++ tends to make things overcomplicated sometimes, a bit more verbal and somewhat cryptic but then again the thinking is different. I have a feeling that C programmers spend less time creating the structure of the program and more time debugging the program while C++ is more like taking care that you have a good structure and that you wouldn't have to debug your program much later. Some weak points that you mentioned about C++ are some of the things I fell into when I was learning it the first time but it's been pretty smooth sailing after that. I don't deal with memory leaks nowadays anymore and generally I don't really spend any time debugging my applications nowadays other than threading race conditions and things like that. Also I do dare to say that in practice C++ programs are not any slower than C programs. I think we can agree that it's mostly about preference of which one you prefer but I don't understand why you wouldn't want to write C code and let the C++ compiler handle it for you? I don't see a reason why you would want to stick to plain C while mixing it with C++ you could still program like in C but with added features like namespaces and even better C++11 constexpr, nullptr and std::swap() function. Keeping it pure C is just shooting yourself in the foot. If you're feeling adventurous a little you could try returning std::vector from a function instead of handling arrays / pointers. C++11 makes returning a temporary std::vector fast btw. And you could do all this while still keeping the functional programming style in your programs. I am genuinely curious why you would limit yourself to just plain C as you can mix all the new C++ stuff to your C style code just fine. Not that you have to reply to me but I don't accept "just evil" as an answer without some serious proof of it. You could use vector class from stl to simplify your coding and making it more sturdy, it's not like you have to start coding classes yourself. Vector class is also really simple to understand, there's nothing mystical about it, it will behave exactly the same way every time.
"C while mixing it with C++ you could still program like in C but with added features.. " Yes I agree. If I was doing C I would add the best features of C++ so its still almost C but just some benefits from C++. Nobody says you have to do OOP if you use C++. Its just optional.
I think there's a saying that "somewhere inside c++ there's a great language". Think that only using a subset of the features is correct c++, different use cases needing different subsets.
I *LOVED* this video. I have been coding C in a very different environment (microcontrollers) for over 15 years. I have been quite isolated, I don't collaborate, and until recently I haven't explored others styles. My coding style and opinions match your own 99.9%. So does my spelling ability, (luckily sublime spell checks comments): 9:43 - Readable not just to you, but to someone else. Sometime in the future, that someone else will be you. 10:04 - I used to avoid abbreviations, (ptr was pointer etc..), but found a screen full of verbose names tiring to look at. I now abbreviate, but very strictly. 31:00 - a massive function, but you didn't break the rule "a function does one thing", if that one thing takes a lot of code, so be it... 39:10 - Strongly agree. And I've spoken those exact same words more than once. 45:48 - I don't use for loops in function code, because they are the only control statement that doesn't read like English. They are useful for wrapping a block in entry/exit code though. 50:12 - I have done the exact same thing, only I integrated it into my own allocater. The file# & line# of the caller are included in each free or used sections metadata, and because my heap is so small I can view it in a hex dump. This is a compile time option of course. I really look forward to checking out your projects.
Hi Michael... I'm just getting into a company based on programming for embedded devices and they have informed me that C will be used extensively.. I'm comfortable in C but for a company while working would really like to get into every aspect in detail... Could you pls guide me on some material be it books vids on where to start and progress to an acceptable or advanced level... Also if you could give me some career advice on whether following the embedded path is good or should I change to something else like web dev etc
@@kshitijbisht6310 Hi. I haven't read many books, but I can offer some advice. Check out Uncle Bob's book "Clean Code", or even just his video talks. It isn't specific to C, but he discusses valuable ways to think about code. Be consistent with your style, and document it for yourself, like this: www.kernel.org/doc/html/v4.10/process/coding-style.html I'm not saying you should copy that style but writing a similar document for yourself will help you to stay consistent. For each module (source file) you write, decide if the module is specific to the application, or if it could be reused in other projects. If it's re-usable, be sure to keep anything application specific OUT of it. Learn how makefiles work. IDE's come and go, make is forever. Any IDE worth it's salt should be able to import a makefile project anyway. WinAVR contains an excellent makefile that I found easy to modify for other platforms. Be thorough with versioning. Commit your changes with git (include notes), use semantic versioning, and track build numbers. Every project should have a GOOD assertion handler. Log assertion failures if you're able to. Have engineering access which can show you if the last reset was due to an error on __FILE__ & __LINE__, and the runtime at which it occurred. The goal is always bug-free code, the assumption that you have achieved that goal is the worst one you can make. Lastly, something I do which is non-standard, but has served me very well for many projects.. In addition to main(), have a main_fly(), anytime your application waits for something, call main_fly(). Modules which require background execution can have an associated _fly() function which gets called in main_fly(). You have to be careful main_fly() doesn't re-enter. As for your career choice, you'll perform best at whatever you're most interested in. Microcontrollers are fun for real time stuff, (motor control, sensors), and low power stuff, like something that runs from a battery for 5 years. I can't speak for other career paths as I'm not on them. One last tip, if you're on windows try switching to Debian or Ubuntu. Oh, and choof is bad for coding, don't smoke choof.
"In the beginning you always want the results. In the end all you want is control." These two lines more or less sum up my 10 years of programming experience.
With my experince - almost seven decades, I think that statement address everything in my life. Except regarding my wife, I still in the beginning. 🙂
@@grimvian 70 years? Damn you must've met Dennis Ritchie himself lol. But joking aside that's awesome.
@@dancom6030 It's over 40 years ago, I got my first computer born with BBC Basic and inline assembler. One second to boot and no noise. So back then, I learned hexadecimal and 6502 assembler.
I could even have met Dennis in the discotheque in the seventies and having beers together, but I did not know English either. :o)
what does he mean control
0:00 intro
5:00 garbage collection is not suitable for high performance scenarios
6:20 prefer stable & concise language features & technology stack
8:25 avoid ambiguity
11:00 don't be "clever"
11:45 be explicit
14:40 static-type language can catch more errors
16:00 early crashes are better than hidden bugs
17:30 improve your developing tools
20:20 general naming convention & coding style
27:20 prefer imperative & sequential code, long functions are OK
31:40 function naming
35:20 API design
36:00 how to organize .h & .c files
38:40 C & OOP-style APIs
41:00 void pointer is your friend to hide internal data
44:18 macros: __FILE__, __LINE__
49:40 a custom allocator for memory debugging
53:10 macro utilities for binary data packing/unpacking
57:10 memory control & pointers
1:03:00 malloc
1:06:00 arrays
1:09:20 struct
1:11:15 inheritance via C pointer casting
1:16:35 struct packing, padding, memory alignment
1:22:55 memory pages, realloc, gflags.exe
1:33:42 memory caches
1:42:30 don't store data twice
1:45:25 trick to reduce allocations: Flexible Array Member
1:48:30 trick to reduce allocations: joint malloc (dangerous)
1:50:48 use "stride" for better handling of Array Of Struct (AOS)
1:53:15 architecture on top of small & flexible primitives
1:55:45 prefer incremental progress
2:00:00 fix code ASAP
2:01:55 UI application design
2:08:50 Carmack's fast square root algorithm
2:09:56 magical random number generator
2:10:30 closing, contacts
Nit: fast sqrt isn't Carmack's. From Wikipedia:
> The algorithm was often misattributed to John Carmack, but in fact the code is based on an unpublished paper by William Kahan and K.C. Ng circulated in May 1986. The original constant was produced from a collaboration between Cleve Moler and Gregory Walsh, while they worked for Ardent Computing in the late 1980s.
I added this list of chapters to SponsorBlock so the users of that extension can see them on the timeline.
Thx
He has a point about 5:00, the biggest optimization you tend to do in GC languages aside from improving the algorithm is minimizing allocations to reduce garbage.
Languages like C#, Java, and Go are massively improving their performance stories. I can really only speak on C# as I’ve been following the changes. Access to CPU instrinsics, stackalloc, no copy slicing, Ahead of time compilation,
These languages have gotten much better in that area, they can definitely reach really high throughput, where the GC can trip you up is in latency sensitive scenarios. Also runtime reflection.. it’s used a bit too willingly by libraries.
I think these days if I really wanted to write in a systems language like C, with a batteries included Stdlib, and explicit control over memory I’d probably use something like Zig.
Keep the core language simple, use type inference, treat types as first class so the language should have the ability to modify types and run expressions at compile time.
Pretty much don’t use macros let type system be expressive enough to do what macros do so everything is type safe.
> 1:11:15 inheritance via C pointer casting
Personally, I think this is Polymorphism concept in OOP instead, fix me I'm wrong.
I've been trying to learn C++ and have realised that C is actually the place for me
same
As a beginner I can't explain how much I appreciate this video. Clear, concise and simplified without sacrificing content. I started with python and am struggling with picking up C. Learning syntax is one thing, learning HOW to apply it is another
I am a college student and C is my first language and now I am learning Python and it feels wrong not putting brackets or semicolons everywhere lol
You hit the point! Some paper I have learned by heart and my mentor pointed me millions of times how to apply things I already knew!
The video is nearing 6 years, yet one of the most profound video on C programming.
When will C99 be old enough though lol
@@draganjonceski2639 Maybe when it’s 25 years old lol
The only thing better than C is HolyC
A statement of Divine Intellect.
True
Amen
RIP Terry A Davis
RIP
"the compiler is your friend when it tells you something is wrong."
This is very true, but the problem with that is that C compilers give the least detailed or useful error messages out of any language I use, not to mention that managed languages give you actual error info at runtime instead of just "segmentation fault."
Edited for clarity.
that js snippet would set x to undefined, not zero
anyway i mostly agree with the stuff in this video but i think the takeaways can be applied to non-garbage-collected languages that are much better than C
or even to garbage collected languages, because GC in a lot of applications is fine
@Simon Farre just don't make errors it takes so much time out of your day as a programmer and one of the things that impacts your efficiency the most
@@Jam_Spam You're expecting people to write thousands of lines of code perfectly without any error whatsoever. are you dumb?
“if you’re gonna be a good programmer, you’re gonna want to learn how to do things” ugh exactly!!!!!! there’s so many phenomenal points in this presentation
-
Although there was a LOT of typos in it 😂 no judgement though
Some where in Nietzsche there is the line - don't think about all the stuff you must know, think about what you must DO.
You are a legend! I've been writing C code for 20 years and you've taught be a few ticks I just hadn't realised until now. Thank you.
I come back to this presentation from time to time. It's given me some good ideas for my own work. Thanks!
Thank you for this. I wish there was more of this kind of content available, but nowadays it's full of "Learn X in 2 hours", "How to make a CLI tool in X", etc. This was something I watched closely and took notes.
Keep coming back to this video. Such a gem.
Awesome, people can dislike, trash all they want but, how many videos like this you see out here? You wanna watch a video on how pointers work? Linked lists? This is real life code and it's awesome that someone took the time to do a video like this. Congrats, man!
Interesting idea.... I found there were better ideas in books on C.
UA-cam recommended this again after a year and I it think this is gonna be one of those videos I come back to every year to pick up new info and see how my C understanding improves
That's exactly how I treat Terry Davis videos/old livestreams
In my third year of my fantastic journey in C programming and I'm still coming back to the C wisdom.
1:42:00 - If you already know the index to remove, you can just use memmove. It's much faster than most people realize because it will invoke SIMD operations and hardware intrinsics to move multiple chunks of memory per cycle. It can actually be faster to memmove an array to remove an element than to remove an element from a linked list using pointer reassignment. Pointers can make things very slow if they aren't used correctly.
I wish I could save comments that is interesting i'll have to test this out.
This boosts my self esteem to program in a way that !not strictly uses design patterns, but the way you understand best! Thanks for sharing!
Started my journey of learning C++ 6 months ago from 0 experience in programming, just watched 16 minutes of your video for the moment but you're already saying "philosophical approach" stuffs I instantly felt during my very young journey.
Very glad to hear my noob "feelings" are not that "heretic" : "why overloading if I could just type few more lines ? why hiding me some details of the code and optimize things I could do myself , getting me bad habits ?" ( especially when learning the roots of how everything work, it's hard to connect the dots lol )
Thanks from a rookie, to help me open my mind in this world :)
Read up on dependency inversion, thats the #1 biggest thing that makes for clean code.
It is the god all mighty of abstraction and code simplification.
“Fuck macros!”
*proceeds to discuss benefits of macros for ten minutes*
something can be bad, but still be useful anyway regardles. but i get what you mean and feel, that was my first impression for a few minutes as well :D
Wow. this guy doesnt even use powerpoint. he uses C for slides :D.
Disappointment he uses Visual Studio
@@bjarnestronstrup9122 lol you expected vim?
@@sharishth Vim is great , Emacs is also acceptable . IDE's are overrated bunch of bloat.
@@bjarnestronstrup9122 nano is love nano is life
@@sharishth Yes nano is alright, but once you get used to vim keybinds everything else seem like torture :).
I'm an intermediate C programmer, and this video was very very helpful and very well put together. Thank you. I wish I saw this immediately after taking a C course!
I'm a Julia programmer (started with C and C++) and I love watching videos on lower level languages like C/C++ and Rust and always appreciate the level of control you can get over your memory.
I love the framing of "Not wanting to manually manage memory but then living in fear of the garbage collector"
I think the reason why people fear the garbage collector is because they don't understand how it works, and then they make mistakes which worsen the impacts of it.
In Julia's documentation there are dedicated sections to the internals of the GC and how to optimize your code so that your code can work in tandem with it.
I've had so many situations where simply tweaking my code according to those guidelines resulted in ~4x speedups and ~3x less garbage collection.
No matter the language, try to learn it inside out to the point where writing optimized code doesn't even require thinking about it.
That adds to his point though, the time spent researching and understanding how to work around your languages garbage collector is time that could have been spent learning how to manage memory instead.
This is insanely useful. Lots of idioms that a JS dev getting into C needs to hear.
Take it with a huge grain of salt. There's a reason why many "new" features have been built to newer versions. This code you are looking at is very outdated. Like, why name something module_object_action when you could use namespaces which is made exactly for that cause (module::object.action). I'd look elsewhere. He also advocates monster functions which is just horrible and completely unmaintainable and unscalable way to code.
Using C in 2020? Come on.. you should be using Rust instead 😂
@@QckSGaming problem with namespace comes when you're in a shared project with multiple programmers.
It gets confusing real fast. In standard libraries yeah it's fine nobody will confuse 'cout', but other than that yeah.....
@@uziboozy4540 old stuff != bad and vice versa, plus everyone have their preference. If you like rust more power to you. People need to try out new stuff especially in tech field.
But disregarding something just due to its age is bad mindset.
@CooCooWizard overrated? Whether or not you think the syntax is garbage, is just your own sensitive opinion.
To me it just sounds like you're either too stupid or too lazy to learn the language.
If you don't like it, don't use it.
Rust is still better than C or C++ without doubt.
Please, elaborate on anything that is better in C/C++ as opposed to in Rust.
I'm not a fan of the way implementation works in Rust, so that's a win for C++ there with classes.
Other than that.. nothing
I would really love to see a whole C tutorial. I have been searching someone like you, who can really teach C. Please, I really insist you to make aa whole tutorial series for C. I am a new CS student. And I absolutely love C. I also want to do some networking, system programming. You tutorials will help me a lot and others too. Please make a series.
Try Casey handmade hero ,chillitomatonoodle and cherno..with some algorithms and books on the side
Try jacob sorber, brian will, brian fraser and barry brown
Don't think you should learn C by following tutorials, it's really a terrible idea, and I speak from personal experience. You become a much better programmer by doing your own projects that you care about, from scratch and try to figure out things as you go, looking up certain things a long the way if you get stuck. Getting stuck in tutorial hell will get you nowhere. Just many hours of videos watched when you could have been making stuff and honing your skills. That being said, C is an amazing language. I come from a C# and JS background and I fell in love with C once I decided to learn it properly. It's so pure in a way, I find that I can focus a lot more of my time of figuring out how to implement functionality in my code rather than worrying about abstractions and things not related to what I'm actually trying to do. Good luck!
@@apresthus87 What you just said, I did that exactly the same way. I wrote that comment 5 months ago. I already learnt C and C++ then. But I wanted to know more From experienced programmers. I did small and also big projects with C and C++. I love lower level things so much, that after 1 and a half year I am still using C and C++. Learning new things, trying frameworks, graphics library etc. I just wanted to know more, thats why I wrote that comment.
@@raihankhan197 That's good to hear! My answer was just as much for beginners that stumble over videos like this. Many beginners get tricked into thinking you can become a good programmer by watching tutorials. I used to be one of them :D I wanted to see how experienced programmers structured the code as I went on instinct more so than anything when making my game engine as my first big C project. I'm happy to hear that you are doing well and still using C though! :)
This is literally one of the best advanced programming talks on UA-cam. 30 years of experience programming and so many "hey that's brilliant moments". Thank you for making this. (You gotta spell check your code comments more though. yeesh!)
fuck spell checking in the comments lmao, we already do enough in the code v:(---
@@Elinzar Well, maybe this one at least : "Acitectectiure" 1:53:22
@@Rafale25 you know somebody is a great programmer if he can't speak human languages anymore
@@Julian-mc3tc that's bullshit bruh. also this talk is kinda trash and culty and is literally anti-intellectual. Science and technology is built on top of common trust and sharing. him trying to prove he is a genius after literally saying don't be clever.
watch jacob sorber or molly rocket :: handmade hero if you actually like building stuff with C. There is also this guy who builds like tiny 8 bit pcs from scratch which is pretty cool.
😂😂@@Julian-mc3tc
the inverse square root works because if you bitcast a floating point to an int you get a decent approximation to the log2 of the number in fixed point.
Then it uses the fact that log2(x)/ 2 (where the bit shift comes into play) equal to log2(sqrt(x)) and a bit more math™ to get a good approximation of the sqrt which is then refined using 1 or 2 newton-raphson iterations.
What🤔🤔🤔🤔🤔🤔
Makes sense
interesting!
You are a crazy mathematician!
@@ekrem_dincel there are several explanations for this on the web. It was popularised due to the source code reveal of quake III, so the algorithm is quite well-known. (Apologies if he said this in the video. I haven't watched that far yet.)
The inheritance using casting absolutely blew my mind. I have a project with a similiar inheritance sturcture and i never thought to do that. Definitely saving this video!
I really support this guy, You can kinda see that he is dyslexic but he tries which you gotta respect. Along with the fact it didn't stop him.
@Abigail Jones Norwegian here! All Swedes are dyslexic. It's part of their culture!
I would prefer a Swedish programmer that do a few spellings errors which the compiler will handle, before a Norwegian fish farming guy with an IQ slightly under the salmon's.
@@tah3460 lol and all Norwegians have a funny bone?
why dyslexic ?
How do you know he is dyslexic?
i love operator overloading, its so expressive. if you don't know what an operation is, don't guess, read the interface
but its much nicer to just see exactly what's happening
@@skejeton if you're not simultaneously using 5 different libraries for vector math, you'll know what "a * b" means everywhere
This has some really good points. In my (admittedly somewhat limited) experience c++ is good/ fine if and only if you are disciplined about the abstractions you create. For whatever problem you are trying to solve, think carefully about what abstractions will make solving the problem easier then implement them, including operator overloading, and then STOP. The rest of the time, build the solution out of those early abstractions and don't introduce new ones unless there's a VERY good reason for it. Then you get the best of both worlds. It doesn't make sense to have to write loops to add two vectors. "+" works perfectly IF you are disciplined about it. That's why c programming experience is vital for good c++ programmers. Coming at c++ from python without c experience will transfer the "wanting results" to c++ code instead of "wanting control" as the video says. Good points, just not quite so absolute.
Agree about C++ being good and having the discipline to not over-engineer your code. I think that can be applied to any language - when I used to write Java and I was still relatively new, I had a habit of getting carried away with class hierarchies and abstractions. At the end of the day the abstractions were mostly useless, and they overshadowed the actual code that solved the problem. Nowadays I do a lot of C++ and I've learned a lot since then. One of the most important lessons was to just build the damn application. You don't need class hierarchies unless you have a very good reason for them, and you shouldn't introduce extra abstractions until you have a clear need for them. Having to refactor some code is not the end of the world.
This is fantastic. So much experience condensed into an easily digestible format. Thank you for sharing!
Having a bit of (theoretical) background in C and C++, just from reading mostly, I've always been hesitant to work in C. Most of that hesitation comes from what I learned in school about OOP and all the do's and don'ts. I've already started doubting much of that since, I always felt it made programming so much harder than it had to be and your video just gave me that extra push.
There is some sexy code. I suppose the guide really reveals the philosophy of c. That’s so satisfying
sexy code
The best thing about C is that it IS actually a very simple and elegant Programming Language and you still get full control of your HW with it. I never understood why so many people hate it so much. As you are pointing out at the beginning, I actually love it for all the reasons other people hate it. Thanks for this very good talk!
project managers hate it, not programmers
@Abigail Jones Link for the debugger?
@@andreika6681 Like always they want a result without minding about mastering the process.
havent seen a computer science major hate it. Programmers who come from shit background are te ones that dislike it
Franz Flasch No, in fact NO. I love C, but even this tutorial is full of undefined behaviour (WHICH is really dangerous) and bad C practices. Do not cast pointers, do not cast structs even when they are identical. Do not ... C is full of DO NOT´s which you really must avoid doing.
22 minutes in, and this is totally my speed right now. This is where I’m at on my journey in learning to use C, and it feels so validating to finally come across something like this. Looking forward to the rest of the video. Thanks for sharing. ☺️
This is a great talk, I have listened to select parts 5 or 6 times. Thanks very much for sharing your experience.
I will be honest, at first I did not like this video too much. However I kept watching until the end and now I think I really like it. I think the parts about why C is the best language and other programming languages aren’t so great could be left out. I really like the deeper knowledge that this video provides. I think this video is not just a great video about C, but rather a great video about computers, programming, and memory through C. Thank you for sharing
12:15
Not a compelling argument at all in my opinion.
Operator overloading mostly makes sense when it's used to define real mathematical operators. (With the exception of string concatenation i guess, and maybe other types)
Operators *ARE* functions. They take data in, they spit data out.
If you're smart enough to understand that "strcat" concatenate two strings together, you're smart enough to understand that '+' concatenate two strings together. Its just another notation to mean the exact same thing.
Using the example of vector multiplication is dishonnest : its ambiguous because there's no clear definition of what a multiplication of vector is. Not because '*' is not explicit in and of itself. And that's why half the people say parwaise mult, and the other half say dot product : They don't know because there's no good anwser.
In fact, i'd like for you to elaborate on why you think "mult_vec (&vecA, vecB, vecC)" is somewhat more explicit than "vecA = vecB*vecC". there's no sementic difference between them... they mean the *exact* same thing. They're Just written differently. Therefore if "mult_vec" is explicit, so is '*'.
I suppose you *DO* use operators on primitive data types ? Why ? Why are they explicit enough ? Because you know what '+', '-', '*', '/', '%' mean on numbers.
In reality, no operator is explicit. You **HAVE** to know what they do to know what to expect from them.
If I'm able to know what an operator does to primitive data types, I don't see why I wouldn't be able to do the same for other data types.
You clearly missed the point.
What an operator does to primitive data-types is clearly and unambiguously defined by the standard. It is guaranteed to remain the same forever, irrespective of the compiler and much less of the person writing the code. With overloading, it is up to whims and fancies of whoever implemented it.
mult_vec (&vecA, vecB, vecC) clearly advertises itself to be a function call, the documentation of which can be looked up. B*C looks like a standard operation when it could be, sans any type info, literally anything.
To make matters worse there could be 100 different overloads of the same '*' operator even for the same type for different second arguments types. My biggest pain when debugging C++ code is that there is no quick way of finding the correct overload or template specialization that is being invoked.
@@karma6746 Also, mult_vec shows that you are _modifying_ an existing object (pass by ref) while a = b * c might return a _new_ object
I agree mostly. It's really a problem of having a feature that risks ambiguity. In C you'll know what uint + uint is assuming basic algebra knowledge (and overflow knowledge). For many it may be unintuitive what uint* + uint does. But the reason that isn't a problem is because it's well known to someone who knows the rules of the language. People can agree that someone who doesn't know the fundamental rules of the language don't count and I think most do. You wouldn't criticize a language because a newbie doesn't get it. They're taken out of the legitimate confusion set. And you need that boundary somewhere. For operator overloading it's not going to be consistent everywhere. I can't hold you to a standard where you have to intuit what every library author chose their vec*vec to mean.
It's a risk averse approach. Not trying to absolutely eliminate confusion.
I'm not personally all that opposed operator overloading. If that's the only interface for types I don't approve of I wrap it. I use it for vector types sometimes. You really just have to check that you know what the operators do before you use them.
I think theres an even better argument IMHO.
You can create your own operators to avoid ambiguity. They're not exactly operators but the resulting code will look as if they were.
stackoverflow.com/a/41780190/7322371
Im guessing the author of the video would hate that solution but in that way we can have both multiplications : vecA vecB , and vecA*vecB, and at this point its obvious which operation we're performing.
@@lupsik1 That is not creating a new operator. It is simply using a (very ugly) hack that overloads the '' operators to make something that looks like a new operator while relying on not one by two operator overloads in the background, not to mention the additional overhead due to the template being used. But that is not even the real problem. There is a reason why C++ only allows existing operators to be overloaded. If a program is filled with multiple such custom 'operators' does it decrease ambiguity or increase it? Imagine trying to debug someone else's code where he has gone wild with those! Your link serves as an even better example of what is wrong with operator overloading. This is the kind of horror that sub-standard programmers create using the features that C++ provides. This is exactly what Linus was talking about in his famous anti-C++ rant. He wasn't against C++, he was against the large number of C++ programmers who don't understand how to write simple, performant, readable, debugable code. The worst part is that these guys don't even understand what they are doing wrong - they think it is cool!
never written a line of c in my life but still watched this
very nice, think i will pick it up soon
I come back from time to time to observe this art!
Excellent demo! I've learned so much concept and programming technique from this video.
Got back to your video after archiving it and I'm pretty pleased.
Great work + love your approach!
I don't even code in C, and here I am 2 hours into this great video
nasheeeeeeeeeeeeee
Hello, I just came across your channel and I'm glad I did. I'm new to programming, the paradigm that most people on youtube teach when talking about programming never has resonated with me. I just don't learn that way. My mind can't think abstractly enough to understand some of the stuff they talk about. I understand things more literally. I've been trying to find resources for quite some time now that would help me get my foot in the door for programming. I've been through the trenches of tutorial hell with several language. From what I've gathered from your lecture is that C can abstract things if you build your program to do so, but it also seems very explicit. Maybe I'm wrong on that. I come from a hardware background, was in the Navy for a long time and have a deep understand of electronics and digital electronics like TTL and IC. I've always wanted to get into programming, mainly because I've always wanted to make a badass game, that was mine. Is there any resources you could share that could help me get started on this journey? Maybe ways to think about the tremendous amounts of mathematical understanding you need to do something like you did with building a graphics rendering in scratch? I think I've made up my mind though, C seems to be the language for me. It's closer to machine code then anything else I've seen, save ASM.
In your Javascript example - 'x' will not be ZERO, but 'undefined'.
Wow! I learned so much in this lecture! A real treasure, cheers!
The examples are very good for understanding the concepts.
I love this talk a lot. Watched it a year or two ago when I was starting out moving over to c from c++. Just re-watched it after actually getting into a c opengl project pretty good. Got a lot more out of it this time. I really agree with your philosophy and found myself doing a few of these "wrong". Gonna incorporate some of these tips. Cache friendly main loop is still eluding me. Thanks for all the sharing you do.
7 years later, still the best C resource on the net.
Nice overview Eskil! I found that people who love C are people who know their hardware. I am one for sure :).
One of the most important video to watch on C. Thanks for sharing this valuable information.
pretty dissapointing video, no indian accent
I WANNA SEE JOMBO 😭
If you squint your ears enough, you'll hear a vaguely Indian accent from his beautiful Swedish voice
A coding tutorial without honking cars in the background.
... and he used a good microphone. ... and there no loud generic techno music playing in the background. Very disappointing indeed.
@Sebastian Oleński He's being sarcastic.
1. About function overloading, I do actually prefer c++ here, as it has a way to specify the type, and be less cryptic about it. It's literals for when that is available or explicitly calling type constructors when not. There is an argument as this is not enforced and implicit type conversions may cause a bug, but when you need it, providing argument type with the arguments themselves, instead of in the function name will force you to change them once you want to edit the function call. As a benefit, you also get arguments types as part of function signature which helps a lot with naming, as while it is good to be explicit, and not have ambiguity, going too much in that direction will lead to code becoming white noise, and it's much harder to not make mistakes, or miss anything while reading.
2. I agree crashes are good, but to me it's obvious that compile time errors are strictly better.
Love the video otherwise
That is true ++
Agree. In general I think any language feature that forces typings from the syntax into the naming tokens (in this case method names) is a bad one. This usually devolves into having to maintain some kind of consistent notation to encode the type into the name in the interface (like Hungarian notation), and quickly becomes unruly.
This is also a case where a compiler could easily warn that one of the arguments is being downcast or whatever in the given example
I absolutely love this so much, thank you!!
"Typing is not a problem"
proceed to make lots of typo LOL
but I agree, that's why we have an editor
yeah, along with refactoring tools to rename things. ;D
I think he deliberately made the typos so other people who steals the video to present to others will look dumb.
"Typing is not a problem"
But reading what you typed is. You need to read this multiple times and that takes your time. And the more time you spend on reading abd understanding the more time you lose on other tasks. We kinfa don't have 3 years to write server for our project, cause during that time it would be outdated enough.
@@TheExiledMeriler See the guys homepage. I think this is some form of learning disorder or so. As you hear, can he speak just fine, so it'ss not about his native origin or so. I know for a fact, that there are disabilities who prevent consistent and correct spelling. That does not impact your ability as programmer, obviously
I think he mentioned that he is dyslexic. So I think we should give him a break :).
Excellent talk.
Especially for the garbage collection i love C and C++
This is so crisp and clear explanation: hope you will make more videos like this
I will try, but im slow...
First half is just "language X does Y which sounds really nice until Z" except you basically never experience Z and Y is absolutely amazing and makes you code faster
People keep telling me you all these features to be effective. So why do people who don't use them keep running circles around the people who do?
@@eskilsteenberg en.wikipedia.org/wiki/Programming_languages_used_in_most_popular_websites
C is 5%, you think they'd catch on? Not to mention the percent of high severity security bugs related to memory problems
@@GanerrrThe web is the jungle my friend. Full of wild animals
I can't even express how much this video helped me grasping SO MANY concepts that I simply couldn't. I no longer program by C coincidence. Thank you!
All of this information is excellent. Anyone writing code should strive to understand all of these concepts no matter what language is being used. This video may be a bit older, but it is still very relevant. Thank you for posting this wonderful content.
The video description needs to be corrected. This is not programming religion, this is programming philosophy, and damn good philosophizing at that. I've learned so much within these 2 hours of watching.
I loved the part where you talk about Acitectectiure. Presentation full of typos, but immensely useful. Thanks a lot. Great content.
Maybe the presenter has dyslexia or something? He's pretty smart, but the only thing I disliked about all this was the amount of typos that I saw.
the thing of allocating arrays on stacks and pointers = arrays are the most important lessons of this video imo.
Wow. I am an undergraduate in comp sci, and oh my goodness… this video opened my eyes to concepts I once thought difficult, but now I have a lot more clarity on them. This was an amazing video
You speaking straights facts for two hours straight, damn.
Whenever I saw the thumbnail with "extren" typo I thought this was a comedy video, like the guy that jokingly uses MS Word as a text editor for coding.
But finally clicked on it and realized it's a serious video; and it's good, thanks
What a great video! Hope more people will be "enlightened" and discover C 's elegance in simplicity.
And for those for whom some of the shortcomings of C would be a deal breaker, I'd suggest looking into Zig. It aims to be "a better C" by doing away with the most "problematic" features and adding some that really should have been there, while still remaining low-level and explicit
i'm gonna be honest, zig is completely unreadable, would probably just use rust instead
@@xydez I'm gonna have to try Zig now.
Rust is almost entirely unreadable to me, just like C++, so if Zig is really that bad, i'm gonna have to stick with Go.
@@epsi the really good thing about rust is enums, they make life a lot easier. Still id suggest you give it a try, its a very nice language once you get the syntax
@@epsi C++ hits the balance just right imo, and it fits in with what he says at the start about how at first you want something to work but later on find yourself wanting extra tools/control that you can't add retroactively.
You can still write that simple C (only major difference is you have to cast to void* explicitly) as much as you like, but when you find that situation where templates will save you hundreds to thousands of lines of code, or where using a class and some overloads lets you just wrap your brain around a problem by just raising the level of abstraction - they're there for you to use.
Or you can shoot yourself in the face with them if you're so inclined
Zig being a better C is almost the same lie told by C++ inventors to make the new language get adopters because they can't make something better than C, the temptation of doing clever stuff is just too much. Zig does have some good points, but it is almost as complicated as rust and c++, and it has some insane stuff like unused variables stop the compiler from processing your code.
Totally agree with all your points. I have a tendency of building everything from scratch but I get demotivated by anyone who hears this (generally). Highly motivated after this ❤
Really cool stuff! I just started writing C, for fun I guess, after years of node.js and before that PHP. I love how simple it is! Everyone talks about the big scary memory management thing, but once I could visualize it, it makes a lot of sense. I’m going to have to rethink something I’m doing with doubly linked lists now, but the ideas of structs having a definite size and structure that’s usable, as well as the ideas of stride and “inheritance” makes something else that was going to become a quadruply linked list much easier and simpler I think! (I have to reason it out still, but this potentially makes my life a lot easier!) Also I love the debugging stuff with macros! Truly ingenious! So far I’ve just been using them to colorize printf output by prepending escape codes automatically xD Sorry for the long comment, but the video contained a lot of gold info to comment on as well!
I'm in the same boat, long time JavaScript dev and I'm starting to code in C for fun in my spare time. The simplicity of the language is just so cool. I don't need to Google around for different frameworks that I need, I can just write them myself!
@@christianbouwense4702 Have learned since I wrote that, that how I think is the best way to write something is often not very efficient in terms of code lines or memory/processor use, but that's learning xD
Strings though... zomg.
strtok is actually destructive and will litter your original string with NULLs. If you need to parse things but still need the original string, keep that in mind.
You can create your own that uses a string buffer and string views (which track the starting and ending point in a struct rather than using null terminators, but keep in mind to convert it back to a string for any functions that require nul terminators or else implement string-view aware versions :)
@@jmrumble Nice, thanks for the info! Yeah I'm still trying to get used to strings and arrays in general. One thing I'm trying to wrap my head around is: if you have a function that takes in an array, is it standard practice to always pass in the array size? Is there any time you can omit the size? And if not, what about strings? 🤔 Should you never assume they're null terminated in a function body?
Very nice talk, filled with valuable advice. Thanks for taking the time.
I learnt why C is superior to all. I only know Python and JS front-end framework. Learning C is a fight worth fighting. Thanks this is an eye opener for eveyone.
I haven't written a single line of C, but this was incredibly insightful for programming in general. thanks for the awesome presentation!
Your memory debugging thing is very neat. Reminds me of ASAN but simpler yet useful.
I'm only 16 minutes in but it looks like I agree with you. I have lost days because something didn't throw an error when it really should have.
I have noticed that clever critiques of programming languages are often used to flex. But in your case, I think you are just thinking for yourself.
11:34 - C++ tries to hide things
55:30 - I've hidden my macro really well
If this isn't meant as a joke, you misunderstood what he meant by saying c++ hides things
It's you hiding something yourself versus the language mandating things stay hidden from you.
@@nextlifeonearth Exactly
@@stewartzayat7526 except it doesn't. in the same way it was the guy's decision to encapsulate that macro, it also was his decision to do the same with the operator overloading example
@@nextlifeonearththis.
control is what you get with c
For some reason I love that your presentation slides are C files with comments in them.
Dude this is how teaching should be. I been really trying to innerstand the concept of what code is doing and why numbers are needed. Why why why. Thank you man ❤
23:32 On this point, most IDEs or even text editors have a "match whole word" option when searching, which looks for word boundaries when searching. This removes the issue of searching "my_function" and getting "my_function_with_stuff" and also works for other types like variables.
recently I've been trying to do some bigger projects and i can affirm that without this video as a reference i would reach insanity before having a functioning build
I started with C and then went to Python. I actually felt uneasy with Python right away because it felt like I had no idea what was going on half the time and stuff was happening by magic. 😅
The most underrated nugget of wisdom is "build a mountain." Everyone thinks those of us that write C code constantly reinvent the wheel or start from scratch. Most of us have been building a mountain for years that all future work just builds upon. It takes awhile to build but once you do, it's yours and you wrote it so your productivity is enormous. You can then focus on debugging your code instead of debugging your knowledge of the language as I find myself doing with languages with ready built mountains like C++ and Rust. It's why I am interested in Zig as their philosophy seems to be in line with this idea of keeping the language simple but slightly higher level of abstraction.
C++ is pretty easy do debug. We build mountains too, even resulting in syntax ≃ to higher level languages.
@@MrAbrazildo Well, this is the debate. OO tends to reduct the total lines of code, but increase the lines of code you have to view when you debug per issue. When you look at the code that triggered the bug, it's hard to tell what is local and what was inherited, patched, subclassed etc.
@@jayflaherty5260 In C++ you can name a list of 'friend's, which says who can access specif data. To breach that security, a bug has to be nasty, usually combining more than 1 error.
And it's possible to craft tools behind operators or classes, which can debug without changing the external code.
@@MrAbrazildo Look at the standard library error messages, I mean, what were they thinking ?
@@Waldganger64 Do you mean exception handling messages? I don't use them.
This video made me realize how C can be superior to every other language, great work. I'm glad I live in a time where this content is readily accessible.
I thought it was already understood that C is the superior language, given its omnipresence.
C is constantly present but not exactly everybody knows/cares about its effect on programming. Being the first significantly high level language, its basically the source of how most programming works today
But it isnt exactly the best language for everything. People like to mention webdev against C as an example but almost anything that needs hardware knowledge is c required
Thank you so much Eskil. Thank you for sharing both; your knowledge and your style.
Now everyone can see that the output is just a reflex of the input, meaning that your software are beautiful because the way you think about how to write it, is beautiful.
There is a large amount of advice and details here that is very difficult to find out alone if you are a beginner.
Gold in the form of a video.
You may spell like a drunken sailor (so do I) but your content and wisdom are pure gold! Thanks!
Immediate like for "C is the greatest language."
Totally 100% agree: I love every feature about C including its limitations. It makes it more elegant, in my opinion: one thing is for sure, I always know exactly what happening (like near the metal) when using C. Or, if I don't, I know that it's completely my fault and not the fault of language weirdness. Everything it does is because I told it to do so.
That's true for every other language too. If you feel like there is language weirdness, then it's still your fault for not knowing it well enough
I do agree with you about the explicitness of C, and you build whatever higher abstractions and libraries that you want to build -- low to high, and full control.
Yeah, who would not love weak typing systems?
How is for witness the fact that int can be 8bit, 16bit, 32bit, or 64bit and even long can be 16bit, 32bit, or 64bit depending on implementation
@@avashurov that's not an issue though, it's not a good idea to ever use "int" or "long", use standard integer types which are guaranteed to have a specific amount of bits
”good code is wide code” has been a game changer for me, as in not being afraid to have long variable names that are descriptive
I agree with everything. I always thought you should have control over memory. People make it sound like this scary thing, wow pointers! memory! so hard!
I honestly realised how simple was memory while working with binary files. It's pretty much the same except certain sizes are padded to be properly aligned.
Plus I wasn't even working with binary files in C but its so related that the realisation hit me in the moment.
Seeing the hang ups that result from this being five years old really shows me how far we have come in 5 years.
You are absolutely correct. C is the only language that i tried which does exactly what i want it to do and not anything more. That's why i love using it, i can just look at c code and tell what it will really do and how the code will compile. It is also a great language as it has no abstraction of the most basic tasks and you have to do them yourself instead of relying on the compiler. Other recent languages are good if you just want something done effortlessly but if you're a programmer or engineer i see no other reason to not use C. The language itself can teach you more about computers and hardware by making you do everything yourself.
C is great for learning and hobby projects but there are real reasons not to use C in production software. The lack of a standard library means that you'll probably be implementing basic data structures yourself in your own quirky way (do we use void pointers? do we use macros to simulate specialization? etc.) The rest of the team will then have to learn your way of doing simple things. And that goes for everything in C - it seems like everyone who does C has their own style and their own convention. That's all overhead that other team members will have to learn to contribute to a C project. Other reasons not to use C for production:
- Spending time implementing basic data structures and algorithms (that should be part of any other standard library) takes time away from building the actual product
- Your custom data structures are much more likely to have bugs or be less efficient than battle-tested ones
- You could use C++ instead and have language conventions and a standard library - plus most of the features from C
"Build a mountain!" This resonates with me. Thanks for creating this video!
Is your approach that because C++ has features that are easy to misuse you should just not use *any* of the features provided?
the add() example would, for example, be an amazing candidate for templates, notice how that would be better, not worse.
With regard to the multiplication example in C++, write better code! Someone writing ambiguous code is not a good argument for not using an entire language, it's an argument for better education.
I don't think we should use C over C++ just because it has less features.
C has it's place, but I don't think it's the same place as C++'s.
Just use selected features of C++ in your C code, and use a C++ compiler. You don't have to use all the features of C++, only use the ones that you want. Any good C++ compiler will accept valid C code.
It's quite frustrating how fan boyish people get. There are useful features to both languages and both features can be abused easily enough. *cough* macros *cough*
I was thinking the same thing. I've heard the "easy to abuse" argument for operator overloading many times, but the problem is that people make intentionally misleading examples. I've written enough Java that I hate writing .add(...) when I really just want a +. That's exactly the time to use operator overloading, not to confuse things.
I as a C++ programmer kind of disagree with you and agree with his perspective. While I personally think using a C++ compiler with select features is the way to go, his overall argument seems to be that writing C code *forces* you to write good, rigorous, "non-clouded" code. Yes, with good programming practices and standards you will theoretically will never misuse any of the features provided, but to me it seems that isn't how it often happens in practice, with many libraries going down a completely unmanageable path because C++ made it easy for them. Again this is just how I see it, but I am a C++ programmer and love the language, so I don't really have a bias in the C direction when it comes to this
this is all fine and dandy until you actually have to cooperate with someone in c++ and you disagree about what's the good minimum subset. Now you don't even know the same programming language as other c++ programmers, and cannot cooperate. Well you can cooperate; just not in c++, but rather in the subset of c++ nearly everybody who programs in it knows/uses: c.
I love your religious beliefs. it sure makes life easy for the most part when programming in C.
These are philosophical beliefs, not religious ones. Philosophy is shaped by reason, whereas faith is not.
There is a bug at 1:50, not enough memory is allocated
You are right! Obviusly it should be: sizeof(MyStructA) + sizeof(MyStructB) . Thanks for spotting it!
Best comment ever.
1:50:00, not 1:50 lmao I was confused
Great talk! So many useful advices for C programmers. Love it!
Content with very skilled competence. After 18 month of C++ and writing two relation databases and tons of training code, I realize, that C must be the future for me. I’m hoping Eskil is making more talks about C. It’s is gold and super interesting. The parts with structs, pointers and memory management is fantastic and explained very well!
Another thing I have picked up from this video: long functions. I have always been taught to “abstract away” and “encapsulate” things and then it becomes an easter egg hunt to find the function within the function within the function! Having however One loop like you suggest that simply does things based on conditions/state and is very clear about that and reads top down like a story book is Sooooo much easier to read when coming back to later. The problem though is that though I like it, other people don’t…
I absolutely wholeheartely disagree to the biggest extend.
The analogy of a story book reading from front to back is sorry to say stupid. If you have a problem with your electric utensils do you want a manual with chapters and subchapters or a block of 200 pages starting in chinese? Finding a bug is not a story, its a specific line.
Imagen this scenario. You have a 2D Game with a gigantic draw loop of 1000 lines of code.
Lets say the drawing of one particular scenario has a bug.
Do you want to a) read through 1000 lines of code, skimming over it ofc, but still 500 lines average.
or b) Follow down a tree of smaller and smaller boxes to zoom down to your scenario? Your IDE is happy to help.
One you skim over 500 lines, where the other you read and think about 10 lines of function names.
Not convinced?
You still have 1000 lines of code and the bug is super hard to find.
Have fun testing one function of 1000 lines of code.
Imagen the stacktrace.
Bug happened at line 643 of function x.
Instead of:
Bug happed at line 13 of function x, called by function y, called by function a called by function f. Which for my example would be something like:
DrawDoomEyeMonster , DrawFlyingMonster, DrawEnemies, DrawGame, Draw
Another point, if someone is a bad programmer the difference between the one line someone hid by accident, is either 20 or 999 lines away.
Whoever says big functions are easier to read is lying or super bad at naming functions.
---
However every rule has its exceptions. If there is no reasonable way to split code, dont. Make sure every function is free of side effects.
@@Schnorzel1337I disagree, strongly. A better example would be a malfunctioning drill that you need to repair. You open it up and troubleshoot the energy lines linearly from the power supply to the end tip. The simpler and the more straightforward the design of the drill, the easier to find where a broken trace or burned component may be. But if the drill has a bunch of smaller different units jumping off from each other it becomes increasingly difficult to see where the energy may flow and it becomes much more time consuming to find where the problem starts
A procedural program is executed from start to end. A bug may start anywhere in that line and make itself manifest anywhere else beyond that point. Tracing that problem back is relatively easy of you have a straightforward block of code to step through. But if you have a backtrace of dozens of functions, tracking where it may start is much, much more time consuming. Especially for something like c, where silent but killer pointer bugs are everywhere
I recommend checking out an article by John Carmack on inlined code (you can google it), he is a lot more terse in explaining why it's a good idea
I write in "C+", I use specific features of C++ that make life easier. I definitely recommend to try that approach.
Can you explain what you mean by that? I'm guessing you mean you write/compile in C++ but you tend to use the base of C with very few pieces of C++ used on a "as needed" kind of basis?
@@jmullentech For example, If I need a priority queue (I am a competitive programmer), I use the one from stl. I compile as c++, but I use raw arrays and memset instead of vectors when I dont need extra vector features such as dynamic memory, etc. When a c++ feature makes life easier, I will use it instead. for example, memset is only for same-byte fill. If I want to fill an array of integers to a value like 1337, memset cant really do that, I use std::fill_n (c++ feature) instead. Stacks, Queues, Sets, etc are really user friendly and implementing them, especially in time limited senarios and competitios is kinda pointless
I believe for every field in C/C++ usages, there exists a right balance between C/C++. In competitive programming for example, stl saves you a crap ton of time. I rushed this explanation since it's 11 PM my time, if ya have any questions hit me up, lior5654#1856 (discord)
@@vtvtify memset is a C function bro, lol
@@SaidMetiche-qy9hb I know, that's the whole point. Re-read the sentence. C is usable within c++, C+ is writing c-style with specific c++ features. Memset in an example of a C featute
@@SaidMetiche-qy9hb oh it was put in the wrong part of the sentence, sry. Editing now
I knew you were going places when you added underscores to make function names more readable. ❤
Love this! The object-oriented part is _very_ good. Not taught at CS programs at university, at least in my case. Sad thing is that novice programmers coming from Java will think pretty much everything said in the video is wrong and bad "design".
Your assumption is completely correct. I am a novice java programmer and this goes against practically everything I've learned thus far. 😅
well, it is bad design. I'm not a novice programmer and I know a lot more than java but this is objectively terrible design. software today is developed by teams who need to be able to read and understand each other's code. modern languages like C++ make this easy for you by providing standard language features to structure your code in a sensible way. the way this guy writes C is his own personal style, not a standard, which means that you need a 2 hour talk to understand it. he also prefers to write tools himself because he doesn't trust libraries (even though said libraries are mature according to him). if every programmer had this piss poor attitude, then nothing important would ever get done. it's just arrogant to expect other programmers to read your code and learn the way you do it when you can't be bothered to learn a library and see how a better programmer does it. it's doubly arrogant to then give a talk on your ass way of writing code as if you're enlightening all the morons who would have been lost without you.
@harleyspeedthrust4013 you are mega retarded. C++ gives you at least half a dozen ways on initialising an int. half a fucking dozen. And you want talk about standardisation. Pull your head our of your ass you dickhead
I love you so much.@@harleyspeedthrust4013
Best take for this video.
You know its good when you enter the video and see controll
As I'm writing this, there are already 255 comments, so...
First post!
(also, great video)
Zeroth post**
Good video that skips HM type systems and how they overcome half of these issues while providing a good chunk of other improvements
I think I still prefer C++ although you make some good points that I agree with. C++ tends to make things overcomplicated sometimes, a bit more verbal and somewhat cryptic but then again the thinking is different. I have a feeling that C programmers spend less time creating the structure of the program and more time debugging the program while C++ is more like taking care that you have a good structure and that you wouldn't have to debug your program much later.
Some weak points that you mentioned about C++ are some of the things I fell into when I was learning it the first time but it's been pretty smooth sailing after that. I don't deal with memory leaks nowadays anymore and generally I don't really spend any time debugging my applications nowadays other than threading race conditions and things like that. Also I do dare to say that in practice C++ programs are not any slower than C programs.
I think we can agree that it's mostly about preference of which one you prefer but I don't understand why you wouldn't want to write C code and let the C++ compiler handle it for you? I don't see a reason why you would want to stick to plain C while mixing it with C++ you could still program like in C but with added features like namespaces and even better C++11 constexpr, nullptr and std::swap() function. Keeping it pure C is just shooting yourself in the foot. If you're feeling adventurous a little you could try returning std::vector from a function instead of handling arrays / pointers. C++11 makes returning a temporary std::vector fast btw. And you could do all this while still keeping the functional programming style in your programs.
I am genuinely curious why you would limit yourself to just plain C as you can mix all the new C++ stuff to your C style code just fine. Not that you have to reply to me but I don't accept "just evil" as an answer without some serious proof of it. You could use vector class from stl to simplify your coding and making it more sturdy, it's not like you have to start coding classes yourself. Vector class is also really simple to understand, there's nothing mystical about it, it will behave exactly the same way every time.
"C while mixing it with C++ you could still program like in C but with added features.. " Yes I agree. If I was doing C I would add the best features of C++ so its still almost C but just some benefits from C++. Nobody says you have to do OOP if you use C++. Its just optional.
I think there's a saying that "somewhere inside c++ there's a great language". Think that only using a subset of the features is correct c++, different use cases needing different subsets.
I *LOVED* this video. I have been coding C in a very different environment (microcontrollers) for over 15 years. I have been quite isolated, I don't collaborate, and until recently I haven't explored others styles. My coding style and opinions match your own 99.9%. So does my spelling ability, (luckily sublime spell checks comments):
9:43 - Readable not just to you, but to someone else. Sometime in the future, that someone else will be you.
10:04 - I used to avoid abbreviations, (ptr was pointer etc..), but found a screen full of verbose names tiring to look at. I now abbreviate, but very strictly.
31:00 - a massive function, but you didn't break the rule "a function does one thing", if that one thing takes a lot of code, so be it...
39:10 - Strongly agree. And I've spoken those exact same words more than once.
45:48 - I don't use for loops in function code, because they are the only control statement that doesn't read like English. They are useful for wrapping a block in entry/exit code though.
50:12 - I have done the exact same thing, only I integrated it into my own allocater. The file# & line# of the caller are included in each free or used sections metadata, and because my heap is so small I can view it in a hex dump. This is a compile time option of course.
I really look forward to checking out your projects.
Hi Michael... I'm just getting into a company based on programming for embedded devices and they have informed me that C will be used extensively.. I'm comfortable in C but for a company while working would really like to get into every aspect in detail... Could you pls guide me on some material be it books vids on where to start and progress to an acceptable or advanced level... Also if you could give me some career advice on whether following the embedded path is good or should I change to something else like web dev etc
@@kshitijbisht6310 Hi. I haven't read many books, but I can offer some advice. Check out Uncle Bob's book "Clean Code", or even just his video talks. It isn't specific to C, but he discusses valuable ways to think about code.
Be consistent with your style, and document it for yourself, like this: www.kernel.org/doc/html/v4.10/process/coding-style.html
I'm not saying you should copy that style but writing a similar document for yourself will help you to stay consistent.
For each module (source file) you write, decide if the module is specific to the application, or if it could be reused in other projects. If it's re-usable, be sure to keep anything application specific OUT of it.
Learn how makefiles work. IDE's come and go, make is forever. Any IDE worth it's salt should be able to import a makefile project anyway. WinAVR contains an excellent makefile that I found easy to modify for other platforms.
Be thorough with versioning. Commit your changes with git (include notes), use semantic versioning, and track build numbers.
Every project should have a GOOD assertion handler. Log assertion failures if you're able to. Have engineering access which can show you if the last reset was due to an error on __FILE__ & __LINE__, and the runtime at which it occurred. The goal is always bug-free code, the assumption that you have achieved that goal is the worst one you can make.
Lastly, something I do which is non-standard, but has served me very well for many projects.. In addition to main(), have a main_fly(), anytime your application waits for something, call main_fly(). Modules which require background execution can have an associated _fly() function which gets called in main_fly(). You have to be careful main_fly() doesn't re-enter.
As for your career choice, you'll perform best at whatever you're most interested in. Microcontrollers are fun for real time stuff, (motor control, sensors), and low power stuff, like something that runs from a battery for 5 years. I can't speak for other career paths as I'm not on them.
One last tip, if you're on windows try switching to Debian or Ubuntu. Oh, and choof is bad for coding, don't smoke choof.