Difference between C and C++: C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off. --Bjarne Stroustrup
Funny story about pure high level software programmers. I did a project once where the microcontroller had 128 BYTES of RAM. Not 128meg, 128K - just 128 BYTES. And I needed 64 of those bytes for dynamic string storage. But I did have 4K of on-chip ROM. So the program was written with many function blocks duplicated in the C code - very few subroutines and those were only one level deep at that. Well a staff programmer not with engineering was highly critical of my "sophomoric" code. "Don't you understand the basics of sub routines?" Well I suggested he re-write the code as efficiently as possible and use all the subroutines you want. Then see if it runs! The big time programmer then got a lesson on stacks and low level microprocessor architecture! There simply was not enough stack space with 64 bytes of RAM left to be jumping around in and out of nested sub routines. But there was more than enough ROM where I could duplicate code blocks.
@@fernandofa2001 ugh.. someone correct me if I'm wrong but I understand it to be as follows: The code is compiled so that it runs from top to bottom, even if it means duplicating code in places.
Similar thing has happened to one of my teachers. He had initially written some code in a for loop, but the code was not running as fast as it should have been. So he has "copied" the code from the loop and "pasted" as many times as the loop was supposed to execute. I have included the words copied and pasted in double quotes because I imagine there was differences between pasted code (different memory location).
I always looked at C++ and C as Delphi is to Borland's Turbo Pascal or Lazarus to Free Pascal Compiler. I had a CS professor tell me (well the class) that he wasn't here to teach us a language, but how to program. Once you know how computers work, and you know how to organize data, a programming language is just a matter of syntaxes. As computer scientists, you should be able to know how and why to do something, and whatever rules you are following for coding is inconsequential.
@Richard Riley It's the difference between being a coder and a programmer. That is what my professor was trying to impress on us. Learning code is just learning a language. You can get tutorials from Oracle to learn Java or watch You Tube videos to learn Python. Buy, if you learn how to create efficient data structures, and how to make logic flow (as a couple of examples), then it doesn't matter the language you use. So, more to what this video was about, C or C++ really doesn't make a difference. C++ offers some tools you'd have to write that aren't already in C. Python offers optimization of certain things over Java. It makes little difference if the concept of code efficiency (use quick sort or merge sort or the 2 3 4 rule for structuring files and directories) is forgien to you.
Yes. but there is also a other side of the coin: OOP patterns were "invented and published" not because programmers are stupid idiots who cannot "invent" them themselves, but in order to give names to these patterns. So, syntax, rules and patterns are the programmers language.
C is C, it is austere but focused. If you use it for any time it's likely you will use most of it. C++ by contrast is many things. It's huge and supports multiple paradigms - some of which are sort of contradictory. I'm not sure anyone uses all of it. The cool thing with C++ is that you can just use the pieces you want. Sometimes just the pieces you want look a lot like C ... that's when you are in C/C++ territory. It would be lovely if lovely if C++ was a perfect superset of C.
@@noop9k Mind naming one? I know of lots of little things. Features that were added that were a mistake, and are still left there for compatibility, but they're mostly pretty minor. *using* is a drop-in replacement for *typedef* , but that means we ended up with both. All the big features seem sufficiently different from one another. My one gripe with the C++ community is that all my interviews thus far have had a narrow focus on inheritance, which I consider a code smell when used too much.
@@elliott8175 The most basic example: zoo of typecast types mostly exists to handle crap like multiple inheritance which is evil to begin with. (Diamond inheritance, virtual inheritance OMG) volatile class member specifier that was deprecated because was so bad. Multiple constructor types you must implement or delete or something very bad can happen accidentally. Recent addition of *byte* The fear of C-style code, need to RAII everything exists purely because of exceptions that can cause resource leakage very easily. Instead of just invoking a C library need to RAII wrap everything and god forbid you forget to implement all the copy/move constructors in your wrapper class properly..
@@noop9k, Yeah, I'd agree with all that, except I think that C++ surely has the best integration with C of all (used) languages, so I'm not sure how that's a negative. Personally, my sense of C++'s biggest downside is its _size._ There are just so many nuances of the language. I still assume lvalue/rvalue, even though I know it's gvalue now, etc. Also "universal referencing" is unintuitive and I wish there was a way to specify that a templated input should be rval without resorting to sfinae/requires.
@@elliott8175 From the C++ FQA: "The real reason to leave the C syntax in C++ was of course marketing - there's absolutely NO technical reason to parse C-like syntax in order to work with existing C code since that code can be compiled separately. For example, mixing C and the D programming language isn't harder than mixing C and C++. D is a good example since its stated goals are similar to those of C++, but almost all other popular languages have ways to work with C code. So IMO all that old syntax was kept for strictly commercial purposes - to market the language to non-technical managers or programmers who should have known better and didn't understand the difference between "syntax" and "compatibility with existing code" and simply asked whether the old code will compile with this new compiler. Or maybe they thought it would be easier to learn a pile of new syntax when you also have the (smaller) pile of old syntax than when you have just the new syntax. Either way, C++ got wide-spread by exploiting misconceptions."
I use both C and C++ everyday in day job. I want to live in a world where we all just get along in big tent community of fellowship. I sincerely like and appreciate both languages.
Agree. I use C APIs from C-like C++. I strictly do _not_ use STL and class-based OO. C-like function pointers/tables and lambdas are the way (not v-tables) for runtime adaptivity (Dr. Alan Kay, AI) and GPU performance. C++ class-based OO is inflexible, and unproductive, and lacks clarity. The "neato" hidden "this" pointer turns out to be nothing but trouble.
It bothers me more then it should when people complain that "C/C++" "is not a language", it's a short hand. It's a whole lot faster than "this generally applies to both C and C++", stop being so obtuse. Nine times out of ten the shorthand "C/C++" is used when comparing them to other languages in a more general sense ("Compilation can make execution faster as is the case with C/C++"), or when talking about more basic features like "how do I make a for loop?", and it's nice to make it known that this answer applies to both languages. Sure there can be lost nuance, and different best practices, but just explain it if it needs explaining. It's the whole GNU/Linux thing over again, though I've no idea which actually came first
The complaint you commented on is valid, since a majority of the times I see that shorthand being used, it's being used to refer to *a* language, not to denote a comparison. A lot of new developers just sort of get the idea that it is a single thing, with C being just an older version of C++, which is not true. Also - GNU came first, in the 1980s. They never really figured out a good kernel in time, so Linux filled that gap and we got GNU/Linux. The more you know! :^)
@@vkoskiv I was more complaining in general, the specific comment in the video has a point but it's not the only time I've seen the sentiment. That being said it's important to differentiate when appropriate, for example, it's super common in C to have a pointer passed as an argument that will eventually hold the result of the function with the return value being a status indicator, and while that's possible in C++ you'd probably be excommunicated for doing it...
It's reducive. It's not even shorter than C, C++. I have never seen anyone use Java/Kotlin, Javascript/Typescript... maybe HTML/CSS for once or twice. The problem is about culture of C++ isn't C, about the people not the language themself. People will hate you when you call them by a different name from what they wanted. If you don't write C, C++ then why insist the term C/C++ on both of them? If you do write C then why you want to mangle yourself with C++ that have very different communities, practices and culture; and vice vesa. It's like the British called the Indians.
"9 times out of ten the shorthand is used when comparing them to other languages....." Tell that to literally every job posting that just says "c/c++". Is it a c job? Or a c++ job? Or both? Is it a c++ job that expects you to write in a c compatible subset?
I wrote embedded code in C for 12 years. I then moved to a new job and was given the chance to look at C++ (something I'd previously dismissed before as inappropriate for embedded). After getting the basics of C++ I realised that I had basically been, unknowingly, reverse engineering C++ in my C code for years! I had manually been designing, writing and debugging features that the C++ compiler gave me for free! Since about 2000 I've not coded for embedded projects in anything other than C++. I found that the C++ code, whilst more abstract, was usually as fast, or faster, than the C it replaced.
Pirates of the Caribbean reference was genius! Personally, I write C in an object oriented way using structs with function pointers inside. When I write C++ code it's pretty much C with classes and a few STL objects like queue, deque, map and so..
@@Mronmovies I have sortof namespaced functions like Surface_Create, Surface_Destroy, Surface_DoSometing clion even lets you do surface.DoSomething and it will autocomplete to the function with the object in the parameter list
Good point. I love C++. I dev firmware code. If C++ couldn’t run lean, if I couldn’t have void * and char * strings, it would be useless to me. The beauty of C++ is being able to travel up and down the complexity and abstraction levels, depending on what you need. The thing that bothers me is the somewhat outdated syntax in C for things like pointers. I mean, were there really no additional special chars other then * that they could have used in the 70s? Probably not. But now it would be cool to have for instance a separate dereference character and a separate address off character. For instance, I would really love to see @ replacing & as the address of operator. And & being strictly a reference symbol. But that’s just wishful thinking obviously. But overall, having the ability in C++ to drop to the lowest of abstraction levels is the thing that makes it C++.
@@peppigue , in my case memory and CPU limitations are very real because of the platform we are targeting so using lower level features of the language is a must to make the project work.
I'm a retired systems programmer for reference. I wrote in C and loved it. My home compiler was Aztec C. At some point they included an extra pre-processor cfront. I dove in. I read standards for fun. I learn each new idiom. Most of my career I wrote in C++. It's my jam. I agree with everything you say. Additionally, I'd add that when someone gives you a list of rules they've forgotten how to improvise. When someone takes the list of rules and considers them the most important thing, not the language or the task, they're toxic. The code they write will drag and be strange and unproductive and liable to lots and lots of otherwise easily avoided bugs. That's all. Just sayin'. Don't @ me
C is simplistic, it gives you the basic tools to build anything, which often begins with building the tools you need to get what you want to get done, done. C++ is not simplistic, coming with many tools that are prebuilt for you in order to simply get things done as well as attempting to protect you from yourself through abstraction. The only issue is that the abstraction of C++ can sometimes make it difficult to track down an issue or understand what's really going on in the background. Still think Bjarne said it best, "With C, it's easy to shoot yourself in the foot. With C++, it's far harder, but when you do, you blow your whole leg off.". Also, never really thought 'char *'s were that complicated, the variable just points to the start of the string which gets read until the null terminator (\0) which is essentially how it's done in assembly.
@@sledgex9 Copying isn't really that hard, if you can get the length of the string you can alloc that many bytes to a new string and simply copy byte by byte until you hit the null terminator. Splitting a string based on a delimiter can be done by simply setting that delimiter to a null terminator and taking a pointer from the character after it then returning the pointer. Concatenating two strings can be done by getting the length of the second string, then extending the first and copying the second starting at the null terminator of the first. The best thing is, there's already a number of functions for all that in string.h.
@@Nacalal It's "hard" because of the tediousness of it and the need to micromanage it. The mental factor is an aspect of it (eg to remember to free at all the exit points).
@@sledgex9 I wouldn't say that's as much difficult as it is a matter of needing to review your code thoroughly, however it can definitely be tedious but that tends to be the case with working around languages that are that low level, that all said, I do personally prefer working with the more simplistic char * strings compared to the more abstracted std::string just simply because it's a less abstracted system and I can better understand how it's manipulated and read in the code. It may not be the ideal solution for everyone but for me it works fairly well, that and I tend to write a lot of my functions to be project agnostic so the tedium of having to write code to handle certain things only really ends up being done once in most cases, for example I have a library I wrote to simplify interacting with libcurl into a single function that gets passed a string for a filename and a string for a URL then downloads whatever's at the link to the given filename, I've been using that same code for years now.
@@sledgex9 Sometimes I seems like people make C programming harder than it is. I simply created a few functions to manipulate strings and I never waste any brain power them, they're fast, and they never crash.
Great video. I like c++. You the programmer choose what features you want to use and how to use them. Glad I learned c and then C++. I understand pointers are not the best but sometimes pointers are quicker and easier to program.
I wrote a complex module in C++. The binary image was over 240 Kbytes. I then rewrote the same module in C. The binary was 47 Kbytes. Encapsulation is easy in C using a pointer to a struct as a handle that's passed to functions, similar to the "this" pointer in C++. The struct can even be in the implementation file, and the header file can declare an opaque handle, which effectively makes the encapsulated data private. Inheritance and especially polymorphism are useful at times, which is why I still write C++. I write mathematical code a lot, and I also find it very useful to overload operators. So, I'm a fan of C++ and a fan of C.
I really like C++, but I've always been a big fan of C, especially because I learned to program in the latter first. Whenever I write C++, I tend to adhere to good old Cish style. I don't see the point in using some of the so-called modern C++ features when there are simple and effective "C" ways to accomplish what's needed. I've been criticized once or twice for treating C++ as "C with smart structs", now I know those people belong to the Little C++ mob and I'm glad I've watched this video 😝
I coded in C for over a decade; I took an active disinterest in C++ during that time. I found the biggest step in moving from C to C++ was finally abandoning the "C with smart structs" coding mental model. I then found myself writing code that was smaller/faster/safer/easier to understand.
Keep stucking in the past. People alr riding car and u still riding horse, and to feel better about urself is to telling urself that everyone else is smol
There's a cppcon talk of Kate Gregory complaining C++ courses get students used to coding C++ like it's C and then switching to the C++ style, as it makes it more difficult and less smooth to then get used to C++.
Haha “character pointers are in your blood” love it. Honestly I like your perspective on this. I’ve been struggling with the little tent C++ culture (work with C++ everyday). So this was a great and refreshing perspective. Thanks!
C gives all that flexibility to C++, so if one rejects C-style on purpose, then probably they have never worked in conditions of strictly limited resources... This is why i teach C then Python and then C++
@@ToolwatchBoutique : He's talking about style, not the language itself. In other words, using all those C++ extra structures makes your program larger (usually). Honestly though C++ compilers are pretty good, so a lot of things it will optimize away anyway.
@@ToolwatchBoutique i mean you are free to choose the most appropriate approaches to achieve the goal, std::string is a cool thing, but you're also free to manipulate with char arrays in a way, that fits best to your needs etc..
@@ToolwatchBoutique Here are a few examples: * Lack of elaboration required at start-up before the main function is started * The ability to write interrupt handlers in a high level language (compiler and architecture dependent) * Full MCDC (Modified Condition/Decision Coverage) for non-trivial applications * Lower call-stack overhead * Deterministic execution times * Robust handling of resource exhaustion * Less reliance on complex libraries of code that cannot be easily replicated and reviewed (template libraries and C++ standard library)
I use C when I don’t need classes, abstractions, and generic types. I use C++ when I need classes, abstractions, and generic types. However, everything is political in 2021. Let all go cry about things that don’t matter.
I use C++ compiler even when I am doing c styled programming, even Bjarne recommends that you can take advantage of a number of features such as namespaces.
I use whatever i find on stackoverflow and gets shit done, who cares if its c or c++ or some type of ansi standard stuff. If the compiler is happy, I'm happy
I've only been programming in C++ for a few years now, so I may not have much authority to say anything on this topic, but one of the reasons I love the language is because it gives you an incredible amount of tools to work with for many different situations. In my opinion, trying to force people to write code with certain guidelines or arbitrary rules is counterproductive for people new to the language. The best way to learn is to try new things, learn about what makes you curious and question rules! Be bold enough to challenge them so that you learn more about it! C++ has so many tools available but they're all useless if you don't know how to use them. To anyone who is relatively new to programming like I was a few years back, always always ALWAYS question things! The best way to become a better coder is to write code.
This is the power of C++ . That is is compatible with C. This means that a C++ application can link against a C library and use it's full functionality. Think about the entire GNU ecosystem, which is written entirely in C. Or large libraries like OpenSSL or OpenGL. You can use these C libraries from a C++ program, without the need of a new library or a wrapper, like in some newborn / modern languages.
As early moderate level programmer I've often found an answer to a problem I've been facing, but it had been in C, so i for some reason just assume oh no, it's C not C++ and ignored it. But now I'm wiser, and know what to look out (and not look out) for.
As a C/C++ developer, I had bought into the "pass by reference" of C++ until I read the Qt Framework's style guide. They had an excellent explanation of why you should pass by pointer if you intend on modifying the value. Specifically, it is a major clue to the caller of your routine: my_function(a, b) versus my_function(a, &b). In the second version, I should know that the value of b is going to be changed. So ... pass by const reference or non-const pointer.
This! I have been thrown off countless times by functions that modify my parameters even though it wasn't obvious they would. Always passing by pointer lifts this ambiguity.
One of the really nice things about C++ is that many of the abstractions are as efficient if not more efficient than the equivalent C code so you can use them even in really constrained environments.
I personally find some of the additional features in C++ over C somewhat useful (like namespaces and methods). I think the main issue is the culture of OOP. There has become this class of programmers who will extol the "virtues" of OOP for every solution even when it makes no sense or causes code bloat.
I feel like you focused mainly on "little C++" and how they get upset about the "C/C++" controversy. It seems like you forgot to mention the other group that gets upset when C is being called a subset of C++.. "modern" C has moved a bit as well in the meantime and the C supported by C++ lacks quite a few interesting parts imho.. But I really don't want to pour oil in that senseless fire, so feel free to not make another video on that topic :P
I try to deviate from C when working in C++, but I really like to use the Standard C functions in C++ when I get a chance. When Bjarne Stroustrup, meant C with classes, I took that personally 😆
Yes, we now see that C with classes is a failed experiment. Later, some features were added to C++ that actually add value, like lambdas, and constexpr. Judicious use of templates e.g. for constants only, e.g. buffer sizes, may also be OK. C++ class-based OO is less flexible, less clear (including hidden "this" pointer), less productive, and less runtime performant than C-like interfaces with function pointers and lambdas. I am a degreed engineer with post graduate work and 30 years corporate experience. C++ OO v-tables cause performance problems for GPUs. C++ OO does not support Dr. Alan Kay's runtime adaptivity, but C function pointers and function tables do. That is important for runtime adaptive software (AI). Do not use the STL, and do not use C++ classes except simple structs with data and function pointers, but no class functions. C23 and C2Y have many features that bring C closer to C++ without the C++ class-based OO and STL. Look at how Rust and Golang allow flexible interface implementation with functions that are more free-standing. Do not be fooled by the STL C++ "cultists". The STL is _garbage_. I very much like Jacob's hash map here. Take _control_ by using C APIs from C-like C++. This is the true "modern" way now. Happy coding, be free!
I very much like Dr. Sorber's teachings and constructs here! Hash map is one of my favorites, and so many other important topics are covered here. Thank you, Dr. Sorber! They are very helpful, and one can build on these with their own C++ (or C) code and use less STL (i.e. less "little C++"), and have more power, control, and understanding, as well as better ability to customize to fit your application.
I've worked in the avionics embedded system industry for nearly 40 years. Started in assembly, moved on to PL/1, Jovial, etc. til achieving Nirvana with C. We're still writing our low-level code in assembly/C, and applications in Ada/C with a bit of C++ thrown in to make the Management Types happy because they're always wanting to ride the latest wave of progress (which looks good on the Marketing slides). We mainly stick to assembly/C because it is far easier to Certify the software where you always* know what is going on (outside of cache) without blowing your budget completely out of the water. That is becoming more and more difficult because even though tools are being created to help, it is also becoming more and more difficult to Qualify the tools we need to help Certify that the code won't go rogue in the middle of a flight. I know how easy it is for even simple code to go bad; it is far, far worse it could be if the complex multi-core, object-oriented, multi-cache, hypervisor-based, safety-critical code decides to go off in the weeds because we humans overlooked a little corner case. *mostly
I don’t really c++ all that much but I’m pretty sure I saw something that said restrict is part of c++ now, or will be in an upcoming standard (c++ 23 maybe?) …
@@lef1970 i heard that restrict doesn't do well with 'this' pointer in C++, so probably restrict won't be coming to standard anytime soon. Though, many compiler extensions 'kind of' support restrict. MSVC has __restrict, GCC has... _restrict_? idk
@@lef1970 There is a co-authored paper by the C and C++ standards committees that, among other things, discusses adding the functionality of 'restrict' using the [[attribute]] syntax. AFAIK, this has only been proposed for standardization, not yet accepted into the standard.
I code in C, and I am currently studying C++. I suggest you make a video (or better yet, a playlist) as a starting point to C++ for people who already know C. Most courses on Udemy, TH-cam et al start from zero.
I always use C++ with SOLID style. I use, hmm, static C++ when I can't afford the runtime overhead. And I use "plain C" when I can't afford to trust compiler optimizations.
Been using C++ for 20+ years, I treat them as separate languages. You can compile C, and link code with a C++ compiler, but not vice versa. Treat them as separate languages, and you will have no issues.
The video seems overall pretty balanced anf fair. I think you may have jumped to conclusions by estimating you wouldn't use "most" C++ features when being under large constraints, as C++ takes "zero cost abstractions" quite seriously and in many cases may even generate less code while being more optimized.
This is essentially the most sensible explanation I've come across when it comes to "C/C++" or "C vs C++", whatever that notation might actually represent.
I experienced that the C++ community is very positive and open to the C community. But if you program in C++ there are reasonable best practices and better ways to do a lot of things, but some of those have to be done consistently to write safe code. It is a myth that C is faster or allows for smaller code. (At least for systems with more than a few tens of kilobyte of RAM.) For safety-critical systems it is a bit easier to avoid any runtime memory allocations with C. But it can also be done with C++.
This reminds me a bit about Kotlin vs Java. You can still use all functions of Java in Kotlin, but there are often nicer and better alternatives on Kotlin that makes everything almost always shorter.
@@atiedebee1020 I can think of a few examples. You can use std::vector and .push_back() instead of malloc and realloc, so you don't have to manage the heap directly in your code. You can use templates to make a bunch of different types of functions instead of having to do something like pass in a void* and specify the size of its type, or make the same function over and over again for each type. Exceptions make error handling less verbose. Things like std::accumulate make summing a collection of numbers less verbose than making a for-loop indexing an array, and it better communicates your intent.
@@somebodyelse9130 wow my comment was very naive. I've recently been trying out some languages a little and I do agree that C++ has quite a few QOL changes. The real verbose language here is java... Idk why I made this comment when I had 0 experience with C++.
I'm a senior with dyslectic issues, who learned a procedural Basic 40 years ago. I read K&R C-book and fall in love with C. The last 12 months I have learned C++. I can now write small working relationsdatabases using pointers including editing without using the string library for learning purposes, search ec. At this stage I still think C++ is endless and find myself using only the keywords. I was using cout, but now I'm using printf, because it feels much more intuitive. I am using encapsulation and composition, but I think a C-programmer, easily can read my code. It was easier for me, to code my own getline instead of struggling and understanding the explanation in cppreference. The Hobby Programmer
I really love this video as it helped me a lot with clarifying my viewpoint. I have been deep in CS, in a way, for 20 years, however I didn't ever get into coding and programming like my Dad did. My Dad (born in 62) came up through all of these languages being invented and developed. He is mostly self-taught with some community college CS. He is a very proficient programmer with a wife knowledge base, as well as being an electrical engineer. As I have been learning to code, I have been focusing a lot on learning the chronology of how we got to where we are, as well as learning C as my root language since everything else seems to be built on top of that. It's been very confusing to see people argue about community standards and already have the knowledge base to see that many people are arguing profusely from either the "I-learned-CS-after-year-2010" camp OR the "I-grew-up-with-this-shit" camp. Trying to find the balance between "you dont have to do it that way anymore" and "its better to do it the low level way and not waste computing power." I find your POV to be what I imagine mine would become if I had your experience.
IMHB although C++ has compatibility with C, it is a language that has been designed and evolved for a different mission. C is almost a high-level assembly, and it is a very brief and close to hardware language, meaning that the language is designed in a way that programmers should implement everything by themselves. In C you almost know what goes on behind the scene, and this perfect control is what embedded or kernel programmers need. C++, however, is made to solve higher level challenges, with the speed and efficiency of C. For example, when you need to use data structures and algorithms to solve a simulation problem, you use the C++ STD library and get thing done easily and efficiently. std::unique_ptr handles objects on the heap (memory) when they go out of scope, and std::vector helps working with arrays as dynamic objects, almost like Python Lists but hundreds of times faster. That is when you realize why C++ is still used and loved by a community of programmers that need abstractions and speed together.
As a friend of my says: "You can program Fortran in any language". And this is the point about C++ as well, the compiler would eat most of the C code, but if you want to program C++, program C++ and don't just use C++ compiler to compile C programs.
For someone like me who uses both for my job I find this strange, I treat both as different languages and switch styles as appropriate. Different tools for different approaches
I like the distinction between bigtent c++ and little c++. in this channel, it really doesn't matter that you use big c++, your goal is to teach C, so you keep things as simple and recoginzable as possible for C programmers. but in c++ spesific channels (and tutorials and websites), i expect to move towards little c++, maybe not throw the big guns of templates and move semantics immediatly, but the code should conform to how the language is (should be) used in practice. The same goes for python or js or any other langauge. you can always do a for loop by getting the lenght and then accessing the element with square brackets. but in most languages this isn't how you do things, and getting comftorable with the 'modern' alternatives for stuff that you can do in classic style is a step towards using feautres that aren't simple in 'base' style. if you dont use std::foreach, you won't use std::erase->std::remove_if and you won't use ranges. if you don't use foreach in C#, you won't use linq. if you map in js, you won't use reduce and whatever else js has. but for this channel. big c++ is fine.
Many people in comment section are arguing if C++ is bad. Some of them are even fighting a programming language on a personal level. A programming language... Can you believe it?
I think "little C++" is so proactive sometimes because c++ has this reputation of a very hard language, while Rust for say, is almost universally loved, "little C++" also sees that c++ has all the tools and potential to achieve "Rust level" of simplicity and elegance, hence Bjarne quote "C++ has a much smaller, simpler language sitting inside it, struggling to get out" and so people push for that Idea of making c++ far simpler. This at least for me is what I feel when I see a tutorial for example using very much C style code, calling it c++. Of course there is no debate, it's perfectly fine code, especially when in context of embedded systems, but the Idea it spreads, that c++ is still that 50 year old language that's very hard to grasp, that is what the problem is, and I'm not sure weather there even is a solution to be honest.
A nice vid Jacob. As you alluded, one just needs to know that C was designed to be just marginally above using a macro assembler about 40+ years ago to write simple operating systems and utilities. We used C language like preprocessors with assembly language to simplify the implementation of control structures such as loops. This would generate the appropriate assembly code so the programmer didn’t need to do it. For modern complex projects where essentially an application runs in its own virtual machine C & its initial function set isn’t really the appropriate language.
If C good enough for Linus Torvalds in 2021, it's definitely good enough for me. If I need to use a high-level and a more elegant language than C, then I have Rust.
I very much disagree that C is just a pre-processor for assembly. It may have started out that way - for the first few years that I was writing C, I was imagining the PDP-11 assembly it was going to produce (even when using other platforms like the M68K, Z8000, x86, etc.), but standard C has gone beyond that. For deterministic programming, especially certain classes of embedded safety critical applications, the power of C++ over C is significantly curtailed, and an attempt to do a bare-metal C++ application with device abstractions, processor exception/interrupt handling, and multi-threading (basically, a real-time executive) is going to be significantly more work and harder to maintain. Using the EC++ (embedded C++) subset helps, but elaboration of static initializers and file or global scope objects still provides major hurdles. EC++ does not have exceptions, multiple inheritance, RTII. No "std::string", no "std::anything", no STL, no "cout". In such environments, you may have multiple virtual address spaces, but you have no dynamic page loading or casting out; you can allocate from the heap, but you cannot ever release memory back to the heap. Not having exceptions, you don't have stack unrolling with automatic calls to destructors, so errors must be handled explicitly all the way up the call chain (which is why you don't have "std::" and can't use other template libraries like "boost"). I use C++ for polymorphism, operator overloading, and a number of other things. I can implement an explicit polymorphism in C, but not operator overloading. My application level code is a mix of C++ and C. My platform code is pure C. I've been programming in C since around 1981, professionally since 1983. In the late 1980s, I worked at a compiler company to improve the optimization and start adding support of features that were in the draft ANSI C standard (function prototypes, for example). I first started using C++ in the early 1990s in the "cfront" era, before templates changed. I've been using both languages ever since then, though I never cared for the over-use of inheritance that is typified by MFC (Microsoft Foundation Classes).
@@filker0 Thanks for the nice reply but there's nothing too disagree about. Didn't say C was just a pre-processor for assembly language. Your reply confirms that contemporary C is now fraught with a myriad of complications from specification changes, additions and complex system architectures. To mitigate such ramifications sets of guidelines such as MISRA C were developed to assist with code (& vehicle) safety. C and Assembly probably will always be around because they're just perfect for their niches.
Objects started with Simula, which came before Smalltalk, and inspired Smalltalk. One of Smalltalk's creators Alan Kay coined the term "object-oriented programming".
Honestly I really get your point but as a cpp user myself I sometimes wish there would be some sort of strict cpp but I know for a fact that this wouldn’t be cpp anymore as it is it’s strength to go as low level as you want and there lies the power.
i really liked how you put your opinions nicely. that's the skill i lack and will have to learn. also, will be looking forward to some of the things you said "topic of another video" :)
The problem with writing C in C++ is not only that you're generally wasting your own time writing code that stdlib already offers (which in itself is a large issue imo), but that a lot of C code is illegal from a standards POV. There's tons of things that you're allowed to do in C that are UB or outright illegal in C++. And compilers like GCC that enables a shit ton of crappy extensions by default doesn't help with this. It's quite easy to write C in C++ and say "oh, this must be valid c++ cause it compiled and runs.. c and c++ are similar", whilst the compiler is lying to you from a ISO POV. Just always compile with -pedantic-errors.
I mainly work with small to medium microcontrollers. Using C, I almost immediately know how the machine code will be generated. With little C++, It is hard.
I love C for my close to the metal realtime audio apps. For maximum abstraction and the use of a determined programming paradigm, I use Common Lisp, which will happily talk to C if need be.
C++11 changed the calculus for performance, specifically multithreading. You can now write programs in a standard way that utilize the multiple cores that modern processor have. C can't do that, at least not without brining in a non standard library (Posix).
3+ years later the especification for C23 was finished, and it bringed several features that made it more compatible with C++, so both languages are getting closer and closer. I hope the C comitee finally makes enough changes to C so it completely becomes a subset of C++, so the interop between them becomes "perfect".
I basically teach C with cin and cout (and some small other c++ features) and still call it C++ because C++ is a combination of structured programming from the C language, plus object oriented programming, plus generic programming. And the first C++ implementation was just C with classes. So... I totally agree with the C/C++ thing. People sometimes go really crazy with the "modern C++" stuff.
Actually, it's fine to use raw pointers in modern c++. Smart pointers only make sense when you're dealing with ownerships. For example, using raw pointers for common implementation of linked list(struct containing "next" pointer) is completely sane thing to do. I dunno, but for me, C++ is basically just use what suits best to get things done, whether it happens to be a classic C-style way, or modern C++, whatever. Something that I don't like about C++ is that there are too many ways to do one thing, and many people fight for 'which one is best'.
Smart Pointers are just generally better. Essentially what they do is ensure you don't have to worry about freeing the memory that you allocate, since they take care of it for you with the destructor. So less memory leaks leads to a better program. Yeah you can use regular pointers but pretty much everytime you run into a bug from either not freeing or double freeing your memory, just remember you could have avoided it if you used a smart pointer.
@@Speed8883 : Well yeah, smart pointers are effectively just wrapper classes that are included in official C++. There's nothing really magical about them, you could write a smart pointer class yourself that holds a pointer and handles the memory allocation/deallocation. Smart pointers are just C++'s standard library that does just that in a generic way with templates that can apply to anything. You could write your own classes to do the same thing, but really, why would you if it's already done for you? But basically the idea is that the only place that memory allocation happens is in those wrapper classes, that way when the class instance is destroyed, it handles the destruction for you. And assuming the compiler optimizes it correctly, it should be a zero-cost abstraction that works the same as if you did it the regular way. So your compiled code is treating it as a naked pointer, but you as the programmer don't have to worry about the hassle of having to worry about freeing it. This is especially important if you ever throw exceptions, because destructors will still work based on the flow of the exception, where you'll need to remember to have special case deletes to free it otherwise (which is a giant pain).
@@taragnor I think you've made my point for me. The smart pointers are template classes that essentially mimic the wrapper classes that programmers have been writing for literal decades. I'm not knocking anyone who does use smart pointers, I just don't like being patronized for using the old-fashioned pointer in a way that meets language standards. Some languages (such as Java) have completely abstracted pointers and memory allocation out of the language entirely. The cost of this is overhead and less control of what's going on under the hood. I'm particularly interested in the Rust approach, in which the compiler itself disallows dangling pointers. Still, C/C++ feels like home.
The way I see it is C++ does a lot of work for you in 2 main areas: 1. It makes your code safer without much or any efforts and therefore less bug-prone. This translates to shorter development cycles. 2. It gives you a basic library that does common tasks fir you, so you don't have to reinvent the wheel or rely on whether you can find a third party library. But there are times where C (even unsafe C) is not only necessary but still required by OS-level functionality. For example, I just did some Linux socket programming and a kernel function call required doing a C-style type cast of an address struct between 2 types that had no common type ancestor. Personally, I would like to see OS-level calls adopt better standards though, rather than compromising things like type safety.
I definitely fall more into your "Little C++" camp, but I completely agree that the point of C++ (and, really, the only niche that sets it apart, as a language) is that it is capable of both low level access to hardware and high level abstractions, making it a competitor for languages like C and for languages like Java and C#. I would really love to find a good course or tutorial on writing the most modern, low level C++ possible, so that it didn't feel like I need to learn the entire modern C language, including its points of deviation from C++, which I won't be able to use, and then sort out what works in C++ and what doesn't on my own. We definitely won't become one community - probably ever - but we should be striving to not only retain, but also to improve upon our ability to get down to the hardware level in C++, and C remains the king of that space.
Just about all low-level C code should compile as C++, such as setting a pointer to a constant value that corresponds to a hardware I/O location, then accessing it as any other pointer. Hardware I/O can be confusing, as writing to a location writes to some (peripheral device) register, but reading that location may read the value of a different register. I/O locations also need to be defined with the volatile keyword, to keep the compiler from optimizing away consecutive reads - the register value can change between two reads, whereas an ordinary memory location won't.
People often use microcontrollers as an excuse for writing c-like code instead of c++, but that point is not valid at all. With microcontrollers you don't have an operating system with virtual memory to take care of allocations and defragment your heap. Using the stack or globals (safely) to avoid allocations is greatly facilitated by things like std::array and generic algorithms (templates), so there's really no excuse for using malloc and code in a c-like style. More over, the difficulty of debugging embedded systems only gets worsen by things like macros, where a single compileable macro oopsie could amount to lost hours debugging something that should not have happened in the first place. (Also, you should use string_view instead of string if you want to replace char*, it's literally free, and does absolutely no heap allocations)
Thanks for making this neat and clean. What is the deal with all the weird embellishments on videos on this topic? I just want to know which one to learn first!
I had to add a comment. I studied both languages. You hit the nail on the head with your statement. However, C is a middle level language very close to a low level and easy to optimize. C++ is a high level language. You still need C to optimize certain code. Even though the compilers are much better. A mater a fact we would add assembly code to C to speed up routines. Yes I was one of those programmers from the 80s. Languages then were classified by low level, medium, and high level.
Little correction: malloc, printf and every other function are not part of the language.They are part of the standard C library. Which is a library. The language itself is very minimal. C++ can run every function, including standard library functions. So your code is a C like C++, but still C++. You ignore the C++ features probably because you are making a point in a specific topic and want to make it as simple as possible (and make a good job in that). Your simplified explanation about the differences lacks a lot and makes it sound like cosmetics with OOP, but it is much more than that. Operator new is part of C++. It is not a standardized replacement of malloc. It is responsible of allocating and than calling the constructor. Using operator
The flexibility of being able use legacy and modern is a blessing and a curse. It all depends on context and your experience level. If you don't know your stuff pointers and unions can be a source of bugs. Used wisely they can give you the performance you need.
On passing pointer arguments, I actually do not like (non-const) reference arguments. As a C++ programmer, I intentionally use `T* arg` if I'm going to modify an argument, rather than `T& arg`, that way it's clear on the calling end that the value could/will be modified. Now, I will use `const T& arg` for non-integral argument types that will not be modified.
I think that conflict is hard to bypass if one has a language(s) that's used so widely. It makes total sense for you to use char* instead of std::string for embedded programming, meanwhile when you write a big computer application it's probably better the other way around. Even new languages without all that legacy can't always steer past these issues. I mean look at Rust and the whole &str vs std::string::String confusion. I've seen many knowledgeable people - especially if they didn't read the Rust book, tho that's somewhat on them - be confused about these 2 alternatives. Anyways, it's really hard to say what to do to fix it. I don't know a way for sure that doesn't also habe a number of disadvantages. And, tho it's easier to say for me as I'm not in that situation, I guess you'll just have to live with it. Making this video statement is the best thing you can do, but that probably won't have a very lasting effect.
I mean, java.lang.String doesn't have that "problem", but I wouldn't call "all strings are immutable and heap allocated" a solution. Imo &str/String is the ideal solution, with no null terminators and easy slicing. Yes, it's harder to learn than just String, but they unify nicely and are more like extensions of the same concept, unlike char* and std::string. C++ probably can't move beyond those two, unfortunately.
@@berylliosis5250 I think I said conflict, not problem. I would not disagree with calling it a problem, but conflict is more specific, and calling it a problem isn't super helpful IMAO, it kind of implies you're able to solve it. And yes, I agree with you. For what Rust is trying to be, and maybe even for a language like Java, a solution like &str/String is probably the best. (yes I'm aware Java doesn't widely use a &str equivalent). And &str is worlds better than null terminated char*. I did not say that, but I agree. It's better when you want to be zero copy, it's safer, it's even better in terms of performance (well, depending on the situation, but it has more flat and predictable performance). There is actually 2 conflicts there. Not sure if I meant both while I wrote this, but I see 2 there now. There's the tradeoffs between &str and String. Nobody has found a straight solution, there likely isn't one, it is not that complex a problem that it's likely so many people smarter than us both have missed it. Than there's the conflict between the way a language is designed, that's meant to address a variety of disciplines, and the various specific disciplines. That &str String difference is an example of that. People that don't care about the performance improvements are confused and maybe annoyed. There's a reason we have so many different languages to this day. People that are concerned with different problems prefer different solutions. I think Rust is doing an excellent job at giving everyone the freedom they need, but it also suffers from that inherent conflict, and in the end sure isn't the right tool for everyone.
@@9SMTM6 Heh, yeah, forget that sometimes. I have rather strong beliefs and preferences (for example, that control over things like copies and allocations is important) and I tend to forget that not everybody has those :P
@@berylliosis5250 yeah, I too had a huge crush on Rust. And it's still my favorite language. But I have stumbled upon a few annoyances. Mostly it's due to the very things I love otherwise, and in the end are tradeoffs, I know only 1 or 2 things I think were genuine errors, and that's very impressive. Eg the orphan rules. Love that they make clear where code is coming from, love what they mean for maintainability. But I'm also regularly annoyed at them, and the newtype + deref pattern is no clean replacement. The thing where I think they genuinely made a mistake is upcasting and downcasting of trait objects. Look at eg downcast-rs and cast_trait_object. These libraries work well enough, but there should not be a need for them. The reason that is so hard in Rust is that they allowed some casts without unsafe that, when combined with the required functionality for these, would not be safe. Another place, where I do not entirely agree with Rusts choices - actually one of the few places where it's too implicit for me - is type inference. Rust has a very powerful type inference algorithm. It needs that in many legitimate situations, eg to figure out type parameters automatically. Where I think they should've limited that powerful type inference is with the "flow of type information". I don't think that eg a vector should be able to infer its value type from a push at a later point. Thats a fairly simple situation in itself, but if you combine a few of them it becomes hard to predict, and when it finally fails because it's lacking required information, it's often hard to recover, since you need to add a lot of types retrospectively. It means that you cant always read the code in one go, but twice, once for the types, once with knowledge of all types.
@@9SMTM6 I support the orphan rules (at the very least over alternatives like C# and Java, where superclasses and interfaces must be _in scope_ before you can implement them). I haven't used trait objects enough for them to become annoying, but that does seem frustrating. Especially where a lang feature is unlikely to fix it for safety reasons. I appreciate the type inference going both directions, but that may be because I haven't really been burned by it. I do think it's not terrible in a world where most people have language extensions that let you see the type (except, unfortunately, in complex cases) I've had plenty of frustrations with Rust too, but nothing near bad enough to want to go to another lang - not cause Rust is so great, but cause other langs just don't have what I want. Sum types, traits, good generics, even the affine type system; programming without them feels incomplete and frustrating. (Actually, I could always try Haskell and Nim, those seem to have what I want)
C and C++ can be seen like being the two hemispheres of the brain… both are a heck useful, but they are separately needed based on the problem or action to resolve or to execute… I think that it’s a child’s play to criticize or to argue the differences of this languages, they are technically brothers! (with a difference in ages) and you could compile and link a hybrid C/C++ codebase and make them work together. I personally love the both, and I consider them the same language, despite the community’s way of thinking.
The real problem of C string is because of a mechanism in C++ and C called "pointer decay". Whenever you pass an array to a function using the pointer, inside that function, there is no way to know what's size of that array and the pointer just becomes a pointer pointing to the first element. That's also the reason why every single C string needed to be null terminated. This is not guaranteed in C string and IS guaranteed in std::string.
My professor at my university ran a class named introduction to programming and required an original game by the 3rd week. Definitely a challenge to a beginner xD
I learned c++ and then c. Then I returned to school and learned a lot more C++. Then in upper division was forced to learn C even more. For some reason, the difficulty in C attracted me. Now on my personal projects I use C for reusable code. At work I use other languages, so it keeps my skills sharps. It def keeps me entertained 😆
If you make it (void*)malloc instead of a real type, it will not work anymore in C++20 is pretty much the only C code I encounter that doesn't easily compiler with C++. Mostly things with void's are what are broken. And the register keyword does nothing in C++. And it doesn't have the... which one is it... restrict keyword. The new utf8 in C++20 also can break old code, but that even breaks C++17 code that didn't heed the deprecation. The way you explain main to new programs is to just show them int main() { return EXIT_SUCCESS; } with no parameters. Also `int main(void)` still works even in C++20, but that would be insane to tell a new programmer and open the void can of worms. C++ cares a lot more about establishing well defined types for every object, even though they can be abstract to the programmer. So casting is a hierarchy and you want to use the weakest form required to get the job done. You would only use c-style cast, which is what the malloc example does, if you needed even more freedom than reinterpret_cast, because C++ wants type safety where C doesn't care what the type is pretty much; "you say it's a char? good enough for me" -- C Compilers. "Why are you calling this int a char? Did you mean to do that? Do you have a good reason? Are you absolutely sure? You know, you could always make a template for this, and I can handle the chars and ints separately for you; it's no trouble at all... oh, you're sure? Well... okay. Enter the authorization codes." -- C++ Compilers
Difference between C and C++:
C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.
--Bjarne Stroustrup
I will take the foot 😆
Nah i just love the simplicity of C, but its not a language i would like to use for production.
That is a surprisingly accurate metaphor lol
I will never program in C++, ever, language sucks and gives me headaches. Rust is what C++ wanted to be.
@@thegrandnil764 well no, we cannot know what C++ wanted to be. It certainly has nothing to do with Go in any way though.
@@thegrandnil764 yo C is simple you should -go- try with C as well 8)
Step 1: Start a .cpp file
Step 2: Use only pure C statements
Step 3: Get cpp fans tears
my teacher do this all the time
Actually, that's exactly what I was doing when knowing C only and doing my C++ college homework xD
A solution to the world's drought problem .
Step 4: Sell the tears and retire as a programmer
that's exactly what i am doing as i learn C in college. no offense
Hey Jacob, what about a "Mind repeating that in C/C++?" t-shirt for the next video, that should blow some minds off... :)
oh my gosh. I would actually buy 10 of those shirts (being that they are iin different colors that is lol).
Funny story about pure high level software programmers. I did a project once where the microcontroller had 128 BYTES of RAM. Not 128meg, 128K - just 128 BYTES. And I needed 64 of those bytes for dynamic string storage. But I did have 4K of on-chip ROM. So the program was written with many function blocks duplicated in the C code - very few subroutines and those were only one level deep at that.
Well a staff programmer not with engineering was highly critical of my "sophomoric" code. "Don't you understand the basics of sub routines?" Well I suggested he re-write the code as efficiently as possible and use all the subroutines you want. Then see if it runs! The big time programmer then got a lesson on stacks and low level microprocessor architecture! There simply was not enough stack space with 64 bytes of RAM left to be jumping around in and out of nested sub routines. But there was more than enough ROM where I could duplicate code blocks.
Isnt that the point of the always_inline keyword in C? (not a statement a question)
@@RobertFletcherOBE I too would like to know
@@RobertFletcherOBE what is that keyword?
@@fernandofa2001 ugh.. someone correct me if I'm wrong but I understand it to be as follows: The code is compiled so that it runs from top to bottom, even if it means duplicating code in places.
Similar thing has happened to one of my teachers. He had initially written some code in a for loop, but the code was not running as fast as it should have been. So he has "copied" the code from the loop and "pasted" as many times as the loop was supposed to execute. I have included the words copied and pasted in double quotes because I imagine there was differences between pasted code (different memory location).
I always looked at C++ and C as Delphi is to Borland's Turbo Pascal or Lazarus to Free Pascal Compiler.
I had a CS professor tell me (well the class) that he wasn't here to teach us a language, but how to program. Once you know how computers work, and you know how to organize data, a programming language is just a matter of syntaxes. As computer scientists, you should be able to know how and why to do something, and whatever rules you are following for coding is inconsequential.
Well said.
Wow.
@Richard Riley It's the difference between being a coder and a programmer. That is what my professor was trying to impress on us. Learning code is just learning a language. You can get tutorials from Oracle to learn Java or watch You Tube videos to learn Python. Buy, if you learn how to create efficient data structures, and how to make logic flow (as a couple of examples), then it doesn't matter the language you use.
So, more to what this video was about, C or C++ really doesn't make a difference. C++ offers some tools you'd have to write that aren't already in C. Python offers optimization of certain things over Java. It makes little difference if the concept of code efficiency (use quick sort or merge sort or the 2 3 4 rule for structuring files and directories) is forgien to you.
Yes, but some rule-sets for writing code are simple, and some are black-holes of complexity.
Yes. but there is also a other side of the coin: OOP patterns were "invented and published" not because programmers are stupid idiots who cannot "invent" them themselves, but in order to give names to these patterns.
So, syntax, rules and patterns are the programmers language.
C is C, it is austere but focused. If you use it for any time it's likely you will use most of it.
C++ by contrast is many things. It's huge and supports multiple paradigms - some of which are sort of contradictory. I'm not sure anyone uses all of it.
The cool thing with C++ is that you can just use the pieces you want. Sometimes just the pieces you want look a lot like C ... that's when you are in C/C++ territory.
It would be lovely if lovely if C++ was a perfect superset of C.
Many of C++ features exist to fix other features, etc.
@@noop9k Mind naming one?
I know of lots of little things. Features that were added that were a mistake, and are still left there for compatibility, but they're mostly pretty minor. *using* is a drop-in replacement for *typedef* , but that means we ended up with both. All the big features seem sufficiently different from one another.
My one gripe with the C++ community is that all my interviews thus far have had a narrow focus on inheritance, which I consider a code smell when used too much.
@@elliott8175 The most basic example: zoo of typecast types mostly exists to handle crap like multiple inheritance which is evil to begin with. (Diamond inheritance, virtual inheritance OMG)
volatile class member specifier that was deprecated because was so bad. Multiple constructor types you must implement or delete or something very bad can happen accidentally.
Recent addition of *byte*
The fear of C-style code, need to RAII everything exists purely because of exceptions that can cause resource leakage very easily. Instead of just invoking a C library need to RAII wrap everything and god forbid you forget to implement all the copy/move constructors in your wrapper class properly..
@@noop9k, Yeah, I'd agree with all that, except I think that C++ surely has the best integration with C of all (used) languages, so I'm not sure how that's a negative.
Personally, my sense of C++'s biggest downside is its _size._ There are just so many nuances of the language. I still assume lvalue/rvalue, even though I know it's gvalue now, etc. Also "universal referencing" is unintuitive and I wish there was a way to specify that a templated input should be rval without resorting to sfinae/requires.
@@elliott8175 From the C++ FQA:
"The real reason to leave the C syntax in C++ was of course marketing - there's absolutely NO technical reason to parse C-like syntax in order to work with existing C code since that code can be compiled separately. For example, mixing C and the D programming language isn't harder than mixing C and C++. D is a good example since its stated goals are similar to those of C++, but almost all other popular languages have ways to work with C code.
So IMO all that old syntax was kept for strictly commercial purposes - to market the language to non-technical managers or programmers who should have known better and didn't understand the difference between "syntax" and "compatibility with existing code" and simply asked whether the old code will compile with this new compiler. Or maybe they thought it would be easier to learn a pile of new syntax when you also have the (smaller) pile of old syntax than when you have just the new syntax. Either way, C++ got wide-spread by exploiting misconceptions."
C IS KING. C STILL RUNS THE WORLD.
I use both C and C++ everyday in day job. I want to live in a world where we all just get along in big tent community of fellowship.
I sincerely like and appreciate both languages.
Always remember, you may die, but C will still be alive.
Agree. I use C APIs from C-like C++. I strictly do _not_ use STL and class-based OO. C-like function pointers/tables and lambdas are the way (not v-tables) for runtime adaptivity (Dr. Alan Kay, AI) and GPU performance. C++ class-based OO is inflexible, and unproductive, and lacks clarity. The "neato" hidden "this" pointer turns out to be nothing but trouble.
@@lordpun6041not really but good idea
It bothers me more then it should when people complain that "C/C++" "is not a language", it's a short hand. It's a whole lot faster than "this generally applies to both C and C++", stop being so obtuse. Nine times out of ten the shorthand "C/C++" is used when comparing them to other languages in a more general sense ("Compilation can make execution faster as is the case with C/C++"), or when talking about more basic features like "how do I make a for loop?", and it's nice to make it known that this answer applies to both languages. Sure there can be lost nuance, and different best practices, but just explain it if it needs explaining. It's the whole GNU/Linux thing over again, though I've no idea which actually came first
The complaint you commented on is valid, since a majority of the times I see that shorthand being used, it's being used to refer to *a* language, not to denote a comparison. A lot of new developers just sort of get the idea that it is a single thing, with C being just an older version of C++, which is not true.
Also - GNU came first, in the 1980s. They never really figured out a good kernel in time, so Linux filled that gap and we got GNU/Linux. The more you know! :^)
@@vkoskiv I was more complaining in general, the specific comment in the video has a point but it's not the only time I've seen the sentiment.
That being said it's important to differentiate when appropriate, for example, it's super common in C to have a pointer passed as an argument that will eventually hold the result of the function with the return value being a status indicator, and while that's possible in C++ you'd probably be excommunicated for doing it...
It's reducive. It's not even shorter than C, C++. I have never seen anyone use Java/Kotlin, Javascript/Typescript... maybe HTML/CSS for once or twice.
The problem is about culture of C++ isn't C, about the people not the language themself. People will hate you when you call them by a different name from what they wanted. If you don't write C, C++ then why insist the term C/C++ on both of them? If you do write C then why you want to mangle yourself with C++ that have very different communities, practices and culture; and vice vesa. It's like the British called the Indians.
"9 times out of ten the shorthand is used when comparing them to other languages....."
Tell that to literally every job posting that just says "c/c++".
Is it a c job?
Or a c++ job?
Or both?
Is it a c++ job that expects you to write in a c compatible subset?
@@khatdubell that's a very fair point
I wrote embedded code in C for 12 years. I then moved to a new job and was given the chance to look at C++ (something I'd previously dismissed before as inappropriate for embedded). After getting the basics of C++ I realised that I had basically been, unknowingly, reverse engineering C++ in my C code for years! I had manually been designing, writing and debugging features that the C++ compiler gave me for free!
Since about 2000 I've not coded for embedded projects in anything other than C++.
I found that the C++ code, whilst more abstract, was usually as fast, or faster, than the C it replaced.
Exactly, you end up doing manually a lot of things, C is really a downgraded C++. But C++ requires a lot more study and skill to be used properly.
Pirates of the Caribbean reference was genius!
Personally, I write C in an object oriented way using structs with function pointers inside.
When I write C++ code it's pretty much C with classes and a few STL objects like queue, deque, map and so..
😀 I do what I can.🌴🏝
Why do you need function pointers? Aren't you passing the instance reference to every one of the "member" functions anyways?
@@alicangul2603 You are correct. I like doing it this way for organization purposes.. it was actually quite popular before C++ came out.
Maybe to emulate a vtable
@@Mronmovies I have sortof namespaced functions like Surface_Create, Surface_Destroy, Surface_DoSometing
clion even lets you do surface.DoSomething and it will autocomplete to the function with the object in the parameter list
Good point. I love C++. I dev firmware code. If C++ couldn’t run lean, if I couldn’t have void * and char * strings, it would be useless to me. The beauty of C++ is being able to travel up and down the complexity and abstraction levels, depending on what you need.
The thing that bothers me is the somewhat outdated syntax in C for things like pointers. I mean, were there really no additional special chars other then * that they could have used in the 70s? Probably not. But now it would be cool to have for instance a separate dereference character and a separate address off character. For instance, I would really love to see @ replacing & as the address of operator. And & being strictly a reference symbol.
But that’s just wishful thinking obviously. But overall, having the ability in C++ to drop to the lowest of abstraction levels is the thing that makes it C++.
well said
Is it only legacy compatibility that rules such things out, or is it more about legacy mindsets?
@@peppigue , in my case memory and CPU limitations are very real because of the platform we are targeting so using lower level features of the language is a must to make the project work.
I'm a retired systems programmer for reference. I wrote in C and loved it. My home compiler was Aztec C. At some point they included an extra pre-processor cfront. I dove in. I read standards for fun. I learn each new idiom. Most of my career I wrote in C++. It's my jam. I agree with everything you say. Additionally, I'd add that when someone gives you a list of rules they've forgotten how to improvise. When someone takes the list of rules and considers them the most important thing, not the language or the task, they're toxic. The code they write will drag and be strange and unproductive and liable to lots and lots of otherwise easily avoided bugs. That's all. Just sayin'. Don't @ me
I agree wholeheartedly. They're hiding behind the constructs of the language.
C is simplistic, it gives you the basic tools to build anything, which often begins with building the tools you need to get what you want to get done, done.
C++ is not simplistic, coming with many tools that are prebuilt for you in order to simply get things done as well as attempting to protect you from yourself through abstraction.
The only issue is that the abstraction of C++ can sometimes make it difficult to track down an issue or understand what's really going on in the background.
Still think Bjarne said it best, "With C, it's easy to shoot yourself in the foot. With C++, it's far harder, but when you do, you blow your whole leg off.".
Also, never really thought 'char *'s were that complicated, the variable just points to the start of the string which gets read until the null terminator (\0) which is essentially how it's done in assembly.
'char *'s become "hard" when you want to do string manipulation, copying, or manual freeing.
@@sledgex9 Copying isn't really that hard, if you can get the length of the string you can alloc that many bytes to a new string and simply copy byte by byte until you hit the null terminator.
Splitting a string based on a delimiter can be done by simply setting that delimiter to a null terminator and taking a pointer from the character after it then returning the pointer.
Concatenating two strings can be done by getting the length of the second string, then extending the first and copying the second starting at the null terminator of the first.
The best thing is, there's already a number of functions for all that in string.h.
@@Nacalal It's "hard" because of the tediousness of it and the need to micromanage it. The mental factor is an aspect of it (eg to remember to free at all the exit points).
@@sledgex9 I wouldn't say that's as much difficult as it is a matter of needing to review your code thoroughly, however it can definitely be tedious but that tends to be the case with working around languages that are that low level, that all said, I do personally prefer working with the more simplistic char * strings compared to the more abstracted std::string just simply because it's a less abstracted system and I can better understand how it's manipulated and read in the code. It may not be the ideal solution for everyone but for me it works fairly well, that and I tend to write a lot of my functions to be project agnostic so the tedium of having to write code to handle certain things only really ends up being done once in most cases, for example I have a library I wrote to simplify interacting with libcurl into a single function that gets passed a string for a filename and a string for a URL then downloads whatever's at the link to the given filename, I've been using that same code for years now.
@@sledgex9 Sometimes I seems like people make C programming harder than it is. I simply created a few functions to manipulate strings and I never waste any brain power them, they're fast, and they never crash.
Great video. I like c++. You the programmer choose what features you want to use and how to use them. Glad I learned c and then C++. I understand pointers are not the best but sometimes pointers are quicker and easier to program.
I wrote a complex module in C++. The binary image was over 240 Kbytes.
I then rewrote the same module in C. The binary was 47 Kbytes.
Encapsulation is easy in C using a pointer to a struct as a handle that's passed to functions, similar to the "this" pointer in C++. The struct can even be in the implementation file, and the header file can declare an opaque handle, which effectively makes the encapsulated data private.
Inheritance and especially polymorphism are useful at times, which is why I still write C++. I write mathematical code a lot, and I also find it very useful to overload operators. So, I'm a fan of C++ and a fan of C.
This needs a double thumbs up man, I couldn't have said this any better!! I am 100% in agreement
I really like C++, but I've always been a big fan of C, especially because I learned to program in the latter first. Whenever I write C++, I tend to adhere to good old Cish style. I don't see the point in using some of the so-called modern C++ features when there are simple and effective "C" ways to accomplish what's needed. I've been criticized once or twice for treating C++ as "C with smart structs", now I know those people belong to the Little C++ mob and I'm glad I've watched this video 😝
I'm in the mood of saying something nice. I like your approach. I hope your programs will turn out well in 2022!
@@SE45CX that was nice
I coded in C for over a decade; I took an active disinterest in C++ during that time.
I found the biggest step in moving from C to C++ was finally abandoning the "C with smart structs" coding mental model. I then found myself writing code that was smaller/faster/safer/easier to understand.
I think you meant "now I can tag those people as _little C++ mob_ and therefore disregard their opinions".
Keep stucking in the past. People alr riding car and u still riding horse, and to feel better about urself is to telling urself that everyone else is smol
There's a cppcon talk of Kate Gregory complaining C++ courses get students used to coding C++ like it's C and then switching to the C++ style, as it makes it more difficult and less smooth to then get used to C++.
Haha “character pointers are in your blood” love it. Honestly I like your perspective on this. I’ve been struggling with the little tent C++ culture (work with C++ everyday). So this was a great and refreshing perspective. Thanks!
C gives all that flexibility to C++, so if one rejects C-style on purpose, then probably they have never worked in conditions of strictly limited resources... This is why i teach C then Python and then C++
@@ToolwatchBoutique Pure simplicity
@@ToolwatchBoutique : He's talking about style, not the language itself. In other words, using all those C++ extra structures makes your program larger (usually). Honestly though C++ compilers are pretty good, so a lot of things it will optimize away anyway.
@@ToolwatchBoutique i mean you are free to choose the most appropriate approaches to achieve the goal, std::string is a cool thing, but you're also free to manipulate with char arrays in a way, that fits best to your needs etc..
@@ToolwatchBoutique And i am not saying C++ doesn't have, on the contrary it does include almost all benefits of C, so why not to use them, if needed?
@@ToolwatchBoutique Here are a few examples:
* Lack of elaboration required at start-up before the main function is started
* The ability to write interrupt handlers in a high level language (compiler and architecture dependent)
* Full MCDC (Modified Condition/Decision Coverage) for non-trivial applications
* Lower call-stack overhead
* Deterministic execution times
* Robust handling of resource exhaustion
* Less reliance on complex libraries of code that cannot be easily replicated and reviewed (template libraries and C++ standard library)
I use C when I don’t need classes, abstractions, and generic types.
I use C++ when I need classes, abstractions, and generic types.
However, everything is political in 2021. Let all go cry about things that don’t matter.
I love a good pragmatist. Thanks for being here.
I use C++ compiler even when I am doing c styled programming, even Bjarne recommends that you can take advantage of a number of features such as namespaces.
@@glee21012 but you also lose some features like `restrict`
I use whatever i find on stackoverflow and gets shit done, who cares if its c or c++ or some type of ansi standard stuff. If the compiler is happy, I'm happy
@@felixbaum2180 If it's good I use it, there is some good C++ stuff on there.
I've only been programming in C++ for a few years now, so I may not have much authority to say anything on this topic, but one of the reasons I love the language is because it gives you an incredible amount of tools to work with for many different situations.
In my opinion, trying to force people to write code with certain guidelines or arbitrary rules is counterproductive for people new to the language. The best way to learn is to try new things, learn about what makes you curious and question rules! Be bold enough to challenge them so that you learn more about it! C++ has so many tools available but they're all useless if you don't know how to use them.
To anyone who is relatively new to programming like I was a few years back, always always ALWAYS question things! The best way to become a better coder is to write code.
4:36 using malloc in c++ is like using mmap in c: yes, you can, yes it's legal, but there's a better option.
This is the power of C++ . That is is compatible with C. This means that a C++ application can link against a C library and use it's full functionality. Think about the entire GNU ecosystem, which is written entirely in C. Or large libraries like OpenSSL or OpenGL. You can use these C libraries from a C++ program, without the need of a new library or a wrapper, like in some newborn / modern languages.
“And programmers saw that it was good” hahahaha! Made me literally LOL
Haha i thought the Same about this sentence 😂
As early moderate level programmer I've often found an answer to a problem I've been facing, but it had been in C, so i for some reason just assume oh no, it's C not C++ and ignored it. But now I'm wiser, and know what to look out (and not look out) for.
Sometimes it's more important what not to do, than what to do.
As a C/C++ developer, I had bought into the "pass by reference" of C++ until I read the Qt Framework's style guide. They had an excellent explanation of why you should pass by pointer if you intend on modifying the value. Specifically, it is a major clue to the caller of your routine: my_function(a, b) versus my_function(a, &b). In the second version, I should know that the value of b is going to be changed. So ... pass by const reference or non-const pointer.
This! I have been thrown off countless times by functions that modify my parameters even though it wasn't obvious they would. Always passing by pointer lifts this ambiguity.
@@gubx42 Then you have to check whether it's nullptr everywhere.
One of the really nice things about C++ is that many of the abstractions are as efficient if not more efficient than the equivalent C code so you can use them even in really constrained environments.
I personally find some of the additional features in C++ over C somewhat useful (like namespaces and methods). I think the main issue is the culture of OOP. There has become this class of programmers who will extol the "virtues" of OOP for every solution even when it makes no sense or causes code bloat.
I feel like you focused mainly on "little C++" and how they get upset about the "C/C++" controversy. It seems like you forgot to mention the other group that gets upset when C is being called a subset of C++.. "modern" C has moved a bit as well in the meantime and the C supported by C++ lacks quite a few interesting parts imho.. But I really don't want to pour oil in that senseless fire, so feel free to not make another video on that topic :P
Much respect for telling it like it is and standing your ground, which is easy because that ground is pretty darn solid.
I try to deviate from C when working in C++, but I really like to use the Standard C functions in C++ when I get a chance.
When Bjarne Stroustrup, meant C with classes, I took that personally 😆
Yes, we now see that C with classes is a failed experiment. Later, some features were added to C++ that actually add value, like lambdas, and constexpr. Judicious use of templates e.g. for constants only, e.g. buffer sizes, may also be OK. C++ class-based OO is less flexible, less clear (including hidden "this" pointer), less productive, and less runtime performant than C-like interfaces with function pointers and lambdas. I am a degreed engineer with post graduate work and 30 years corporate experience. C++ OO v-tables cause performance problems for GPUs. C++ OO does not support Dr. Alan Kay's runtime adaptivity, but C function pointers and function tables do. That is important for runtime adaptive software (AI). Do not use the STL, and do not use C++ classes except simple structs with data and function pointers, but no class functions. C23 and C2Y have many features that bring C closer to C++ without the C++ class-based OO and STL. Look at how Rust and Golang allow flexible interface implementation with functions that are more free-standing. Do not be fooled by the STL C++ "cultists". The STL is _garbage_. I very much like Jacob's hash map here. Take _control_ by using C APIs from C-like C++. This is the true "modern" way now. Happy coding, be free!
I very much like Dr. Sorber's teachings and constructs here! Hash map is one of my favorites, and so many other important topics are covered here. Thank you, Dr. Sorber! They are very helpful, and one can build on these with their own C++ (or C) code and use less STL (i.e. less "little C++"), and have more power, control, and understanding, as well as better ability to customize to fit your application.
I've worked in the avionics embedded system industry for nearly 40 years. Started in assembly, moved on to PL/1, Jovial, etc. til achieving Nirvana with C. We're still writing our low-level code in assembly/C, and applications in Ada/C with a bit of C++ thrown in to make the Management Types happy because they're always wanting to ride the latest wave of progress (which looks good on the Marketing slides). We mainly stick to assembly/C because it is far easier to Certify the software where you always* know what is going on (outside of cache) without blowing your budget completely out of the water. That is becoming more and more difficult because even though tools are being created to help, it is also becoming more and more difficult to Qualify the tools we need to help Certify that the code won't go rogue in the middle of a flight. I know how easy it is for even simple code to go bad; it is far, far worse it could be if the complex multi-core, object-oriented, multi-cache, hypervisor-based, safety-critical code decides to go off in the weeds because we humans overlooked a little corner case. *mostly
This is my new favorite channel! Thanks for posting these vids.
You're welcome. Glad you're enjoying them.
C/C++ is one tool, which is important.
You are so right in that C++ learners just can’t grasp the C part and get frustrated.
C has a feature that c++ doesn't, restrict
I don’t really c++ all that much but I’m pretty sure I saw something that said restrict is part of c++ now, or will be in an upcoming standard (c++ 23 maybe?) …
@@lef1970 i heard that restrict doesn't do well with 'this' pointer in C++, so probably restrict won't be coming to standard anytime soon. Though, many compiler extensions 'kind of' support restrict. MSVC has __restrict, GCC has... _restrict_? idk
ah I'm pretty sure there are some others infact the docs has a list of difrences that makes c code not do the same or not compile
@@lef1970 There is a co-authored paper by the C and C++ standards committees that, among other things, discusses adding the functionality of 'restrict' using the [[attribute]] syntax.
AFAIK, this has only been proposed for standardization, not yet accepted into the standard.
@@reubenfrench6288 ok thx for the information - I’ll google it
I code in C, and I am currently studying C++. I suggest you make a video (or better yet, a playlist) as a starting point to C++ for people who already know C. Most courses on Udemy, TH-cam et al start from zero.
I always use C++ with SOLID style.
I use, hmm, static C++ when I can't afford the runtime overhead.
And I use "plain C" when I can't afford to trust compiler optimizations.
Been using C++ for 20+ years, I treat them as separate languages. You can compile C, and link code with a C++ compiler, but not vice versa. Treat them as separate languages, and you will have no issues.
The video seems overall pretty balanced anf fair. I think you may have jumped to conclusions by estimating you wouldn't use "most" C++ features when being under large constraints, as C++ takes "zero cost abstractions" quite seriously and in many cases may even generate less code while being more optimized.
This is essentially the most sensible explanation I've come across when it comes to "C/C++" or "C vs C++", whatever that notation might actually represent.
I experienced that the C++ community is very positive and open to the C community. But if you program in C++ there are reasonable best practices and better ways to do a lot of things, but some of those have to be done consistently to write safe code. It is a myth that C is faster or allows for smaller code. (At least for systems with more than a few tens of kilobyte of RAM.) For safety-critical systems it is a bit easier to avoid any runtime memory allocations with C. But it can also be done with C++.
Jacob this was outstanding.
This reminds me a bit about Kotlin vs Java. You can still use all functions of Java in Kotlin, but there are often nicer and better alternatives on Kotlin that makes everything almost always shorter.
I don't think C++ makes anything shorter
@@atiedebee1020 I can think of a few examples. You can use std::vector and .push_back() instead of malloc and realloc, so you don't have to manage the heap directly in your code. You can use templates to make a bunch of different types of functions instead of having to do something like pass in a void* and specify the size of its type, or make the same function over and over again for each type. Exceptions make error handling less verbose. Things like std::accumulate make summing a collection of numbers less verbose than making a for-loop indexing an array, and it better communicates your intent.
@@somebodyelse9130 wow my comment was very naive. I've recently been trying out some languages a little and I do agree that C++ has quite a few QOL changes. The real verbose language here is java... Idk why I made this comment when I had 0 experience with C++.
I totally agree with this. Very good to hear these things, cheers
I'm a senior with dyslectic issues, who learned a procedural Basic 40 years ago. I read K&R C-book and fall in love with C. The last 12 months I have learned C++. I can now write small working relationsdatabases using pointers including editing without using the string library for learning purposes, search ec. At this stage I still think C++ is endless and find myself using only the keywords. I was using cout, but now I'm using printf, because it feels much more intuitive. I am using encapsulation and composition, but I think a C-programmer, easily can read my code. It was easier for me, to code my own getline instead of struggling and understanding the explanation in cppreference.
The Hobby Programmer
I really love this video as it helped me a lot with clarifying my viewpoint. I have been deep in CS, in a way, for 20 years, however I didn't ever get into coding and programming like my Dad did. My Dad (born in 62) came up through all of these languages being invented and developed. He is mostly self-taught with some community college CS. He is a very proficient programmer with a wife knowledge base, as well as being an electrical engineer.
As I have been learning to code, I have been focusing a lot on learning the chronology of how we got to where we are, as well as learning C as my root language since everything else seems to be built on top of that. It's been very confusing to see people argue about community standards and already have the knowledge base to see that many people are arguing profusely from either the "I-learned-CS-after-year-2010" camp OR the "I-grew-up-with-this-shit" camp. Trying to find the balance between "you dont have to do it that way anymore" and "its better to do it the low level way and not waste computing power." I find your POV to be what I imagine mine would become if I had your experience.
IMHB although C++ has compatibility with C, it is a language that has been designed and evolved for a different mission. C is almost a high-level assembly, and it is a very brief and close to hardware language, meaning that the language is designed in a way that programmers should implement everything by themselves. In C you almost know what goes on behind the scene, and this perfect control is what embedded or kernel programmers need.
C++, however, is made to solve higher level challenges, with the speed and efficiency of C. For example, when you need to use data structures and algorithms to solve a simulation problem, you use the C++ STD library and get thing done easily and efficiently.
std::unique_ptr handles objects on the heap (memory) when they go out of scope, and std::vector helps working with arrays as dynamic objects, almost like Python Lists but hundreds of times faster. That is when you realize why C++ is still used and loved by a community of programmers that need abstractions and speed together.
Thanks Jacob. I never felt the need to work in c++ since I use c only for systemlevel programming and there it gets the job done so easy
As a friend of my says: "You can program Fortran in any language". And this is the point about C++ as well, the compiler would eat most of the C code, but if you want to program C++, program C++ and don't just use C++ compiler to compile C programs.
For someone like me who uses both for my job I find this strange, I treat both as different languages and switch styles as appropriate. Different tools for different approaches
"Everybody wants to rule the world" Line from a song in the 80s about the time C++ was muturing 😉
I like the distinction between bigtent c++ and little c++.
in this channel, it really doesn't matter that you use big c++, your goal is to teach C, so you keep things as simple and recoginzable as possible for C programmers.
but in c++ spesific channels (and tutorials and websites), i expect to move towards little c++, maybe not throw the big guns of templates and move semantics immediatly, but the code should conform to how the language is (should be) used in practice.
The same goes for python or js or any other langauge. you can always do a for loop by getting the lenght and then accessing the element with square brackets. but in most languages this isn't how you do things, and getting comftorable with the 'modern' alternatives for stuff that you can do in classic style is a step towards using feautres that aren't simple in 'base' style.
if you dont use std::foreach, you won't use std::erase->std::remove_if and you won't use ranges.
if you don't use foreach in C#, you won't use linq.
if you map in js, you won't use reduce and whatever else js has.
but for this channel. big c++ is fine.
Many people in comment section are arguing if C++ is bad. Some of them are even fighting a programming language on a personal level. A programming language... Can you believe it?
I think "little C++" is so proactive sometimes because c++ has this reputation of a very hard language, while Rust for say, is almost universally loved, "little C++" also sees that c++ has all the tools and potential to achieve "Rust level" of simplicity and elegance, hence Bjarne quote "C++ has a much smaller, simpler language sitting inside it, struggling to get out" and so people push for that Idea of making c++ far simpler. This at least for me is what I feel when I see a tutorial for example using very much C style code, calling it c++. Of course there is no debate, it's perfectly fine code, especially when in context of embedded systems, but the Idea it spreads, that c++ is still that 50 year old language that's very hard to grasp, that is what the problem is, and I'm not sure weather there even is a solution to be honest.
Such an informative video! Nice job.
A nice vid Jacob. As you alluded, one just needs to know that C was designed to be just marginally above using a macro assembler about 40+ years ago to write simple operating systems and utilities. We used C language like preprocessors with assembly language to simplify the implementation of control structures such as loops. This would generate the appropriate assembly code so the programmer didn’t need to do it. For modern complex projects where essentially an application runs in its own virtual machine C & its initial function set isn’t really the appropriate language.
If C good enough for Linus Torvalds in 2021, it's definitely good enough for me. If I need to use a high-level and a more elegant language than C, then I have Rust.
I very much disagree that C is just a pre-processor for assembly. It may have started out that way - for the first few years that I was writing C, I was imagining the PDP-11 assembly it was going to produce (even when using other platforms like the M68K, Z8000, x86, etc.), but standard C has gone beyond that. For deterministic programming, especially certain classes of embedded safety critical applications, the power of C++ over C is significantly curtailed, and an attempt to do a bare-metal C++ application with device abstractions, processor exception/interrupt handling, and multi-threading (basically, a real-time executive) is going to be significantly more work and harder to maintain. Using the EC++ (embedded C++) subset helps, but elaboration of static initializers and file or global scope objects still provides major hurdles. EC++ does not have exceptions, multiple inheritance, RTII. No "std::string", no "std::anything", no STL, no "cout". In such environments, you may have multiple virtual address spaces, but you have no dynamic page loading or casting out; you can allocate from the heap, but you cannot ever release memory back to the heap. Not having exceptions, you don't have stack unrolling with automatic calls to destructors, so errors must be handled explicitly all the way up the call chain (which is why you don't have "std::" and can't use other template libraries like "boost").
I use C++ for polymorphism, operator overloading, and a number of other things. I can implement an explicit polymorphism in C, but not operator overloading. My application level code is a mix of C++ and C. My platform code is pure C.
I've been programming in C since around 1981, professionally since 1983. In the late 1980s, I worked at a compiler company to improve the optimization and start adding support of features that were in the draft ANSI C standard (function prototypes, for example). I first started using C++ in the early 1990s in the "cfront" era, before templates changed. I've been using both languages ever since then, though I never cared for the over-use of inheritance that is typified by MFC (Microsoft Foundation Classes).
@@filker0 Thanks for the nice reply but there's nothing too disagree about. Didn't say C was just a pre-processor for assembly language. Your reply confirms that contemporary C is now fraught with a myriad of complications from specification changes, additions and complex system architectures. To mitigate such ramifications sets of guidelines such as MISRA C were developed to assist with code (& vehicle) safety. C and Assembly probably will always be around because they're just perfect for their niches.
Objects started with Simula, which came before Smalltalk, and inspired Smalltalk. One of Smalltalk's creators Alan Kay coined the term "object-oriented programming".
Honestly I really get your point but as a cpp user myself I sometimes wish there would be some sort of strict cpp but I know for a fact that this wouldn’t be cpp anymore as it is it’s strength to go as low level as you want and there lies the power.
i really liked how you put your opinions nicely. that's the skill i lack and will have to learn.
also, will be looking forward to some of the things you said "topic of another video" :)
You make me smile. I totally agree with you.
The problem with writing C in C++ is not only that you're generally wasting your own time writing code that stdlib already offers (which in itself is a large issue imo), but that a lot of C code is illegal from a standards POV. There's tons of things that you're allowed to do in C that are UB or outright illegal in C++. And compilers like GCC that enables a shit ton of crappy extensions by default doesn't help with this. It's quite easy to write C in C++ and say "oh, this must be valid c++ cause it compiled and runs.. c and c++ are similar", whilst the compiler is lying to you from a ISO POV. Just always compile with -pedantic-errors.
Dude! Loved the Pirates reference
At my current level, C++ is pretty much "C with namespaces and nicer strings" :p
Loved it lol. I hate being told, "you need to use STL features", when I don't want to.
I mainly work with small to medium microcontrollers. Using C, I almost immediately know how the machine code will be generated. With little C++, It is hard.
Totally agreed, thats why I prefer to start learning C before diving into C++
I love C for my close to the metal realtime audio apps. For maximum abstraction and the use of a determined programming paradigm, I use Common Lisp, which will happily talk to C if need be.
Great! Thank you very much for your honest standpoint. I absolutely agree.
C++11 changed the calculus for performance, specifically multithreading. You can now write programs in a standard way that utilize the multiple cores that modern processor have. C can't do that, at least not without brining in a non standard library (Posix).
When you try to utilize multiple cores, you won't use posix or C++ APIs for that, you use OpenMP and you can do that in C too.
POSIX is the standard OS platform.
3+ years later the especification for C23 was finished, and it bringed several features that made it more compatible with C++, so both languages are getting closer and closer. I hope the C comitee finally makes enough changes to C so it completely becomes a subset of C++, so the interop between them becomes "perfect".
your explanation is very clear thank you ! i started following from turkey 🙏
welcome
I basically teach C with cin and cout (and some small other c++ features) and still call it C++ because C++ is a combination of structured programming from the C language, plus object oriented programming, plus generic programming. And the first C++ implementation was just C with classes. So... I totally agree with the C/C++ thing. People sometimes go really crazy with the "modern C++" stuff.
I've been using C++ for 26 years and I still refuse to use that stupid C++ iostream interface with its
@@SerBallister Why? Sure the choice to go with operator
@@valizeth4073 precision and formatting qualifiers. Type safety isn't an issue if you pay attention and test correctly
Thank you for the defense of pointers. I can't seem to pass pointers as arguments without being patronized for not using std::unique etc
Actually, it's fine to use raw pointers in modern c++. Smart pointers only make sense when you're dealing with ownerships. For example, using raw pointers for common implementation of linked list(struct containing "next" pointer) is completely sane thing to do.
I dunno, but for me, C++ is basically just use what suits best to get things done, whether it happens to be a classic C-style way, or modern C++, whatever. Something that I don't like about C++ is that there are too many ways to do one thing, and many people fight for 'which one is best'.
Smart Pointers are just generally better. Essentially what they do is ensure you don't have to worry about freeing the memory that you allocate, since they take care of it for you with the destructor. So less memory leaks leads to a better program. Yeah you can use regular pointers but pretty much everytime you run into a bug from either not freeing or double freeing your memory, just remember you could have avoided it if you used a smart pointer.
@@taragnor I get that, but didn't wrapper classes accomplish that already?
@@Speed8883 : Well yeah, smart pointers are effectively just wrapper classes that are included in official C++. There's nothing really magical about them, you could write a smart pointer class yourself that holds a pointer and handles the memory allocation/deallocation. Smart pointers are just C++'s standard library that does just that in a generic way with templates that can apply to anything. You could write your own classes to do the same thing, but really, why would you if it's already done for you?
But basically the idea is that the only place that memory allocation happens is in those wrapper classes, that way when the class instance is destroyed, it handles the destruction for you. And assuming the compiler optimizes it correctly, it should be a zero-cost abstraction that works the same as if you did it the regular way. So your compiled code is treating it as a naked pointer, but you as the programmer don't have to worry about the hassle of having to worry about freeing it. This is especially important if you ever throw exceptions, because destructors will still work based on the flow of the exception, where you'll need to remember to have special case deletes to free it otherwise (which is a giant pain).
@@taragnor I think you've made my point for me. The smart pointers are template classes that essentially mimic the wrapper classes that programmers have been writing for literal decades. I'm not knocking anyone who does use smart pointers, I just don't like being patronized for using the old-fashioned pointer in a way that meets language standards.
Some languages (such as Java) have completely abstracted pointers and memory allocation out of the language entirely. The cost of this is overhead and less control of what's going on under the hood.
I'm particularly interested in the Rust approach, in which the compiler itself disallows dangling pointers. Still, C/C++ feels like home.
When i look at the comments, i see alot of C knowledge. You should start a community in discord!
The way I see it is C++ does a lot of work for you in 2 main areas: 1. It makes your code safer without much or any efforts and therefore less bug-prone. This translates to shorter development cycles. 2. It gives you a basic library that does common tasks fir you, so you don't have to reinvent the wheel or rely on whether you can find a third party library. But there are times where C (even unsafe C) is not only necessary but still required by OS-level functionality. For example, I just did some Linux socket programming and a kernel function call required doing a C-style type cast of an address struct between 2 types that had no common type ancestor. Personally, I would like to see OS-level calls adopt better standards though, rather than compromising things like type safety.
`C with classes` was the original name of c++
Yes but back then it really wasn't C++.
Thank you for incorporating one of my favorite movie quotes
Excellent points, I totally agree!
This is such a great video!
I definitely fall more into your "Little C++" camp, but I completely agree that the point of C++ (and, really, the only niche that sets it apart, as a language) is that it is capable of both low level access to hardware and high level abstractions, making it a competitor for languages like C and for languages like Java and C#.
I would really love to find a good course or tutorial on writing the most modern, low level C++ possible, so that it didn't feel like I need to learn the entire modern C language, including its points of deviation from C++, which I won't be able to use, and then sort out what works in C++ and what doesn't on my own.
We definitely won't become one community - probably ever - but we should be striving to not only retain, but also to improve upon our ability to get down to the hardware level in C++, and C remains the king of that space.
Just about all low-level C code should compile as C++, such as setting a pointer to a constant value that corresponds to a hardware I/O location, then accessing it as any other pointer. Hardware I/O can be confusing, as writing to a location writes to some (peripheral device) register, but reading that location may read the value of a different register. I/O locations also need to be defined with the volatile keyword, to keep the compiler from optimizing away consecutive reads - the register value can change between two reads, whereas an ordinary memory location won't.
I love writing in C/C#, it's such a great language.
How to annoy little C++ AND little C:
goto
windows.h is not compatible with C++
the linux kernel is full of goto's
People often use microcontrollers as an excuse for writing c-like code instead of c++, but that point is not valid at all. With microcontrollers you don't have an operating system with virtual memory to take care of allocations and defragment your heap. Using the stack or globals (safely) to avoid allocations is greatly facilitated by things like std::array and generic algorithms (templates), so there's really no excuse for using malloc and code in a c-like style. More over, the difficulty of debugging embedded systems only gets worsen by things like macros, where a single compileable macro oopsie could amount to lost hours debugging something that should not have happened in the first place.
(Also, you should use string_view instead of string if you want to replace char*, it's literally free, and does absolutely no heap allocations)
Thanks for making this neat and clean. What is the deal with all the weird embellishments on videos on this topic? I just want to know which one to learn first!
where do people find the time to write entire paragraphs about C/C++ under a youtube video
It's amazing what people find time for. 😬
I had to add a comment. I studied both languages. You hit the nail on the head with your statement. However, C is a middle level language very close to a low level and easy to optimize. C++ is a high level language. You still need C to optimize certain code. Even though the compilers are much better. A mater a fact we would add assembly code to C to speed up routines. Yes I was one of those programmers from the 80s.
Languages then were classified by low level, medium, and high level.
Little correction: malloc, printf and every other function are not part of the language.They are part of the standard C library. Which is a library. The language itself is very minimal.
C++ can run every function, including standard library functions. So your code is a C like C++, but still C++. You ignore the C++ features probably because you are making a point in a specific topic and want to make it as simple as possible (and make a good job in that).
Your simplified explanation about the differences lacks a lot and makes it sound like cosmetics with OOP, but it is much more than that.
Operator new is part of C++. It is not a standardized replacement of malloc. It is responsible of allocating and than calling the constructor.
Using operator
Good points. Thanks, Ronny. Yes, time was short. An exhaustive comparison would have taken a while. Feel free to send lists or make videos.
The flexibility of being able use legacy and modern is a blessing and a curse. It all depends on context and your experience level. If you don't know your stuff pointers and unions can be a source of bugs. Used wisely they can give you the performance you need.
Techincally one must learn C first then learn C++
Legacy code is still being used 👌
I remember when my IT teacher claimed to be teaching 'C/C++' as in we were able to use features from both languages.
On passing pointer arguments, I actually do not like (non-const) reference arguments. As a C++ programmer, I intentionally use `T* arg` if I'm going to modify an argument, rather than `T& arg`, that way it's clear on the calling end that the value could/will be modified. Now, I will use `const T& arg` for non-integral argument types that will not be modified.
I think that conflict is hard to bypass if one has a language(s) that's used so widely.
It makes total sense for you to use char* instead of std::string for embedded programming, meanwhile when you write a big computer application it's probably better the other way around.
Even new languages without all that legacy can't always steer past these issues. I mean look at Rust and the whole &str vs std::string::String confusion. I've seen many knowledgeable people - especially if they didn't read the Rust book, tho that's somewhat on them - be confused about these 2 alternatives.
Anyways, it's really hard to say what to do to fix it. I don't know a way for sure that doesn't also habe a number of disadvantages. And, tho it's easier to say for me as I'm not in that situation, I guess you'll just have to live with it. Making this video statement is the best thing you can do, but that probably won't have a very lasting effect.
I mean, java.lang.String doesn't have that "problem", but I wouldn't call "all strings are immutable and heap allocated" a solution.
Imo &str/String is the ideal solution, with no null terminators and easy slicing. Yes, it's harder to learn than just String, but they unify nicely and are more like extensions of the same concept, unlike char* and std::string.
C++ probably can't move beyond those two, unfortunately.
@@berylliosis5250 I think I said conflict, not problem. I would not disagree with calling it a problem, but conflict is more specific, and calling it a problem isn't super helpful IMAO, it kind of implies you're able to solve it.
And yes, I agree with you. For what Rust is trying to be, and maybe even for a language like Java, a solution like &str/String is probably the best. (yes I'm aware Java doesn't widely use a &str equivalent).
And &str is worlds better than null terminated char*. I did not say that, but I agree. It's better when you want to be zero copy, it's safer, it's even better in terms of performance (well, depending on the situation, but it has more flat and predictable performance).
There is actually 2 conflicts there. Not sure if I meant both while I wrote this, but I see 2 there now.
There's the tradeoffs between &str and String. Nobody has found a straight solution, there likely isn't one, it is not that complex a problem that it's likely so many people smarter than us both have missed it.
Than there's the conflict between the way a language is designed, that's meant to address a variety of disciplines, and the various specific disciplines. That &str String difference is an example of that. People that don't care about the performance improvements are confused and maybe annoyed.
There's a reason we have so many different languages to this day. People that are concerned with different problems prefer different solutions.
I think Rust is doing an excellent job at giving everyone the freedom they need, but it also suffers from that inherent conflict, and in the end sure isn't the right tool for everyone.
@@9SMTM6 Heh, yeah, forget that sometimes. I have rather strong beliefs and preferences (for example, that control over things like copies and allocations is important) and I tend to forget that not everybody has those :P
@@berylliosis5250 yeah, I too had a huge crush on Rust. And it's still my favorite language. But I have stumbled upon a few annoyances. Mostly it's due to the very things I love otherwise, and in the end are tradeoffs, I know only 1 or 2 things I think were genuine errors, and that's very impressive.
Eg the orphan rules. Love that they make clear where code is coming from, love what they mean for maintainability. But I'm also regularly annoyed at them, and the newtype + deref pattern is no clean replacement.
The thing where I think they genuinely made a mistake is upcasting and downcasting of trait objects. Look at eg downcast-rs and cast_trait_object. These libraries work well enough, but there should not be a need for them. The reason that is so hard in Rust is that they allowed some casts without unsafe that, when combined with the required functionality for these, would not be safe.
Another place, where I do not entirely agree with Rusts choices - actually one of the few places where it's too implicit for me - is type inference. Rust has a very powerful type inference algorithm. It needs that in many legitimate situations, eg to figure out type parameters automatically.
Where I think they should've limited that powerful type inference is with the "flow of type information". I don't think that eg a vector should be able to infer its value type from a push at a later point.
Thats a fairly simple situation in itself, but if you combine a few of them it becomes hard to predict, and when it finally fails because it's lacking required information, it's often hard to recover, since you need to add a lot of types retrospectively.
It means that you cant always read the code in one go, but twice, once for the types, once with knowledge of all types.
@@9SMTM6 I support the orphan rules (at the very least over alternatives like C# and Java, where superclasses and interfaces must be _in scope_ before you can implement them).
I haven't used trait objects enough for them to become annoying, but that does seem frustrating. Especially where a lang feature is unlikely to fix it for safety reasons.
I appreciate the type inference going both directions, but that may be because I haven't really been burned by it. I do think it's not terrible in a world where most people have language extensions that let you see the type (except, unfortunately, in complex cases)
I've had plenty of frustrations with Rust too, but nothing near bad enough to want to go to another lang - not cause Rust is so great, but cause other langs just don't have what I want. Sum types, traits, good generics, even the affine type system; programming without them feels incomplete and frustrating. (Actually, I could always try Haskell and Nim, those seem to have what I want)
C and C++ can be seen like being the two hemispheres of the brain… both are a heck useful, but they are separately needed based on the problem or action to resolve or to execute…
I think that it’s a child’s play to criticize or to argue the differences of this languages, they are technically brothers! (with a difference in ages) and you could compile and link a hybrid C/C++ codebase and make them work together.
I personally love the both, and I consider them the same language, despite the community’s way of thinking.
The real problem of C string is because of a mechanism in C++ and C called "pointer decay". Whenever you pass an array to a function using the pointer, inside that function, there is no way to know what's size of that array and the pointer just becomes a pointer pointing to the first element. That's also the reason why every single C string needed to be null terminated. This is not guaranteed in C string and IS guaranteed in std::string.
My professor at my university ran a class named introduction to programming and required an original game by the 3rd week. Definitely a challenge to a beginner xD
I learned c++ and then c. Then I returned to school and learned a lot more C++. Then in upper division was forced to learn C even more. For some reason, the difficulty in C attracted me. Now on my personal projects I use C for reusable code. At work I use other languages, so it keeps my skills sharps. It def keeps me entertained 😆
If you make it (void*)malloc instead of a real type, it will not work anymore in C++20 is pretty much the only C code I encounter that doesn't easily compiler with C++. Mostly things with void's are what are broken. And the register keyword does nothing in C++. And it doesn't have the... which one is it... restrict keyword. The new utf8 in C++20 also can break old code, but that even breaks C++17 code that didn't heed the deprecation. The way you explain main to new programs is to just show them int main() { return EXIT_SUCCESS; } with no parameters. Also `int main(void)` still works even in C++20, but that would be insane to tell a new programmer and open the void can of worms. C++ cares a lot more about establishing well defined types for every object, even though they can be abstract to the programmer. So casting is a hierarchy and you want to use the weakest form required to get the job done. You would only use c-style cast, which is what the malloc example does, if you needed even more freedom than reinterpret_cast, because C++ wants type safety where C doesn't care what the type is pretty much; "you say it's a char? good enough for me" -- C Compilers. "Why are you calling this int a char? Did you mean to do that? Do you have a good reason? Are you absolutely sure? You know, you could always make a template for this, and I can handle the chars and ints separately for you; it's no trouble at all... oh, you're sure? Well... okay. Enter the authorization codes." -- C++ Compilers
char8_t is the new C++20 type that breaks old utf8 code, I mis-worded that.
laugh in const_cast LOL.
The mighty reinterpret_cast can't cast away constness. C-style cast don't give a hoot.