Тёмный

My Rant on C++ 

gingerBill
Подписаться 11 тыс.
Просмотров 25 тыс.
50% 1

Опубликовано:

 

30 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 204   
@alefratat4018
@alefratat4018 5 лет назад
I started by learning C then C++. I have been using C++ for 10 years in my professional life but went back to C for all of my personal projects. Actually, the more I improve as a programmer, the more I appreciate C. I love its simplicity and *minimalism*. With C++, especially modern C++, you have so many ways to do the same thing that it becomes overwhelming. With C, it forces me to do things in a *simple* and *straightforward* way. No fancy stuff, just the bare minimum.
@coldcircuit99
@coldcircuit99 4 года назад
C is an abomination of an tool. I don't hate people for using it or like it but a programing language is nothing but a tool and if a tool is failing in being able to give me advantage for a problems that I encounter then it is a failure.
@MrApplewine
@MrApplewine 4 года назад
I've heard stories where you could do something in C++ with three lines of code which would take over 1000 lines of C or something like that. So, are you aware of situations like that?
@alefratat4018
@alefratat4018 4 года назад
@@coldcircuit99 And yet C is present everywhere unlike any other language. Not really a failure, don't you think ?
@alefratat4018
@alefratat4018 4 года назад
@@MrApplewine No
@WouterStudioHD
@WouterStudioHD 4 года назад
@@alefratat4018 Yes, with templates. You create a template for a linked list, now you don't have to write one for each new type. C is fun, but nowhere near as expressive as C++ (can be). The reason that you see C on every platform is because it is close to the metal. You don't see C++ everywhere, because writing a C++ compiler is about the hardest thing anyone could ever do. C is way simpler to compile. C does however have big memory problems, that C++ also has inherited. Rust would in most cases be the ultimate language for low level work.
@knofi7052
@knofi7052 Год назад
Don't rant, just write your own compiler and call it ODIN...😉
@kavorka8855
@kavorka8855 3 года назад
I fully agree! I'm a an embedded engineer and have been using C all my life. I used C++98/11 in the past but recently I started to take a look at c++17/20, what a mess! What a stupid language! This is not about unnecessary, silly complexity of modern C++, but much more. Every feature, every step has 20 rules and exceptions. A tour of C++ by Bjarne Stroustrup: "The behavior of out-of-range access to a string_view is unspecified. If you want guaranteed range checking, use at(), which throws out_of_rang e for attempted out-of-range access, use a gsl::string_span (§13.3), or ‘‘just be careful.’’ " Yes, "just be careful!"! I think using c++ at least for embedded systems is a crime! Its stupid to say the least!
@kayomn
@kayomn 6 лет назад
I didn't have any real complaints with C++ until I started using D.
@aa-wv9oy
@aa-wv9oy 5 лет назад
Unfortunately D cant replace c++ even now
@simivb
@simivb 3 года назад
D really feels like its in beta though. There are so many compiler bugs, obvious holes in the features and strange design decisions. After the initial delight of "finally some actual compile-time meta-programming" I got to "they didn't really learn anything" very quickly.
@kayomn
@kayomn 3 года назад
@@simivb I came to this same conclusion when I stopped using the ecosystem they provided and started trying to do anything system-level. D quickly falls apart and you realize just how much of the language relies on the runtime features. I'd compare it to a better C#, but it did not end up replacing C++ in my personal projects due to the above reason.
@etodemerzel2627
@etodemerzel2627 3 года назад
Yeah, D was nice at first, but then quickly became a disappointment. Currently, I'm really enjoying Zig. It's more like C, but modern and friendly.
@instant_apples1513
@instant_apples1513 8 лет назад
As someone who has been using C++ heavily for many years, I think I might be able to contribute here. A) Exceptions are a vital part of software. Error codes encourage a heavily procedural style of code, which is not always suitable. Exceptions allow errors to be handled in a generic, automatic way, so when a team member is writing code, they can safely assume that no errors are silently ignored. Beyond that, error codes are slower than exceptions in the non-exceptional case (exceptions trade space for time). B) In my years of using C++ professionally, I have very very rarely (like maybe twice) seen a constructor that can fail. Even then, you wouldn't write the try-catch directly around the object construction. That entirely defeats the purpose. The exception will usually be caught higher up. C) Do you honestly want to be writing "defer destroy_thing()" after every call to "create_thing()"? What if you forget? What if a team member forgets? Memory leak, deadlock, or worse. What if the object is destroyed too soon? Destructors serve the exact same purpose as defer, and are automatically called, with no room for human error, and they don't clutter your code. (Although I do use a "defer" macro when working with OpenGL because its resource management is barbaric.) D) I don't understand how your "static duck typing" example is different from templates. One less line of code? Regarding OOP, it's just another style of coding. C++ doesn't force it upon you, it's just there if you want it. People coming from a Java background will probably want OOP, while someone coming from OCaml can just pretend it's not there. I've worked on several C++ projects that don't use inheritance. E) In my experience, move semantics operate seamlessly with the language. I can now return an array from a function without copying it, and not once do I have to type "&&". In fact, I almost never type "&&" because moves are mostly implicit. That's all. There are a lot of things I dislike about C++, even more than you gave, but I have to disagree with most of your points here. I just get the feeling that you never really gave most of these features a chance, or never worked on a large team. Thanks for reading this far.
@GingerGames
@GingerGames 8 лет назад
+instant_apples Thank you for watching and commenting. Here are a few replies for each section: A) I prefer to handle errors as conditions within the code there and then. Exceptions make you deal with the errors elsewhere and makes them very obscure. Returning an error is good but that does not imply returning an error code. And error could be a struct/pointer-to-struct with much more information and still easy to use. Also, I prefer not have errors if I can. If it is something such as file io, networking, etc. then this is unavoidable but I still want to handle the errors there and then. I am not worried about the performance in this case as if these types of errors happen, speed is the least of my worries. B) The whole reason exceptions were created was to allow for error handling within ctors and dtors. As you have said, if you have not seen this virtually ever, then doesn't this defeat the original purpose of exceptions in C++? C) I do prefer to write and read that. It is clear to the reader and shows intent. I've been using Go at work and you hardly need to write `defer`. When you do, it's not something that you will forget as it becomes a pattern you get in to. If you open something, you close it; if you create something, you destroy it; if you lock something, you unlock it. It's clear and explicit and optional. D) The difference between my "static duck typing" and templates is that this only applies to polymorphic functions. It's more of a restriction/check so that only certain types can be added. I want functional-style functions that I use generic types but have type safety and restrictions. Templates do not solve the restriction/check and produce dreadful code. C++ Templates are technically a separate language within C++ (they are turing complete); I would rather write in C++ to do my metaprogramming -- why can I not? I know you can use a subset of the language but using a big code base and other numerous libraries, it difficult to make sure people do not use and OOP features. E) Move semantics are good in some respects but they do not always work (especially depending on the compiler (_MSVC_)) which does require me to write `&&`. They do work for some things like what you have said but ownership and the things related to `&&` are not by default in the language (similar to the mutability thing in C++). In languages like Rust, ownership is the default (so is immutability), so this is not an issue. It's not that I don't like the idea of R-value references but that they are tacked on. My main point is that I trying to decide what I want from a language at the moment and most of the features/tools that C++ provides do not help me solve the problems I have. If C++ solves the problems you have then that is the language is for you but not for me. The problems I have are: * memory layout and access * custom memory allocation (and context) * metaprogramming * generic types * concurrency * building projects (time and complexity)
@instant_apples1513
@instant_apples1513 8 лет назад
+Ginger Games Good response. I suppose I'll say "fair enough" to most of your points here, with a few comments. A) I suppose if you're writing an entire application, error codes are fine. And I totally agree with simply not having errors. But when writing a library, sometimes an error could invalidate some preconditions of a future state, and if the person using your library ignores an error code, it might cause a crash, or even cause machinery to dangerously malfunction. With exceptions, I have a guarantee that either the user will catch and handle it, or the entire program will terminate safely. B) RAII is necessary for exceptions, but exceptions are not necessary for RAII. It is true that constructors cannot return error codes, and this could be considered a flaw, but constructors shouldn't fail anyway. And destructors cannot throw exceptions by default anyway. C) In C++, files are closed, mutexes are unlocked, and memory is freed automatically. I don't see how making it explicit helps, and I certainly won't trust the new hires to remember to do so. D) I'll be the first person to complain about how crazy templates can get, but you certainly can statically restrict types to certain interfaces and such. For example: ideone.com/p7jzYX . If you remove the concept and static_assert, everything still works, but with horrible error messages. E) Rust's lifetime and ownership semantics are definitely the best around, no argument here, although I never personally felt like move semantics were tacked on to C++ (it feels more like they were missing before). We are fighting the same problems. The hoops we have to jump through to get good allocation in C++ are reserved only for our most talented team members, because nobody else can even read the code. And we have team members dedicated to improving compile times. I think we definitely do need a better language. But for now, C++ is the only one that lets my team solve problems pragmatically, while also providing the abstractions and safety that fit our whole team. C is too hardcore, Java is too simple, Rust is too new, and anything else is too slow.
@GingerGames
@GingerGames 8 лет назад
instant_apples Good points. Again it's all opinions and preferences at the end of the day; what I like is to be explicit and not hide things. If you like RAII then use it, I am not going to stop you. I'm thinking that future languages will start be more domain specific, such as Rust and Go, and I think this will be a better thing in the long run. Languages don't need to be completely general purpose as they will be spread to thinly. I am really hoping people start using languages that are right for their domain rather than "one size fits all" approach that it is at the moment. In mathematics and the sciences, this is already the case with Julia, Mathematica, R, etc. but the rest of the industry, this is not the case. C and C++ are the only realistic solutions for low level programming for modern hardware. Rust looks promising but it is still not the language for me. Go is very good and solves my server programming issues but not anything else. Thank you for the discussion.
@chastitywhiterose
@chastitywhiterose 4 года назад
One thing I really like is that there is no shortage of opinions on C and C++. I like hearing people's opinions but it really doesn't influence the way I write code at all. I stick with ansi C all the time and have used C++ a few times and written a class but it really is just another way to do the same thing I could do in C without the OOP.
@skipdrill373
@skipdrill373 2 года назад
Finally a C89 programmer. So why do you prefer C89 over C11?
@chastitywhiterose
@chastitywhiterose 2 года назад
@@skipdrill373 Mostly because I care about legacy software the most. I like the idea of being used to the style of code that would have been used to develop code in the 80s. Plus I am used to it.
@richtw
@richtw 8 лет назад
Agreed with a lot of that. As a professional game developer for nearly 20 years, working with C++14 and enduring build times of >20 minutes every time I touch a core header, I'd love to take a step back away from the increasing complexity of C++ and look at things in a less abstract and more pragmatic way. Apart from the injection of 'invisible' code through constructors and destructors (which can make code far harder to reason about), the language encourages you to forget what's going on at the low level with regard to allocation and suchlike (there was some recent revelation that Google Chrome unwittingly makes 25000 allocations every time you press a key!). The OOP model is outdated, and excessive dynamic dispatch, particularly in loops, has a profound adverse effect on performance, as I've discovered on a number of occasions. Having also gone back to pure C for personal projects (I thought I was the only one!), I certainly find myself missing certain C++ features, and I too have mused on how a new language built on C might look. I've also found myself pulled in the completely opposite direction - that of functional programming. While it might not really be an appropriate paradigm for games or low-level programming (from a performance perspective), something which appeals to me is its application of immutability and value semantics in order to trivially leverage parallelism. I would predict that in the next 10-15 years, PCs with 32+ cores will start to become commonplace, and we developers are going to have to embrace development for multiple cores as a given, and the more that any language helps out with that, the better. I don't suppose there's any clear way to reconcile functional idioms and C's strictly procedural medium-level approach, but it's interesting to wonder if the best of both worlds could be taken, and what kind of crazy language that might look like. Encouraging use of value semantics by default might be an interesting area to look at, leaning on the optimizer to turn pass-by-value into pass-by-reference unless the passed value is mutated by the callee. C also needs something like lambdas, in order to be able to match the performance of C++ in certain kind of generic functions, where the optimizer can inline the lambda instead of it being pulled out as a separate call-to-pointer-to-function. As much as I love C, I still can't imagine a large-scale multi-developer project using it these days. Add multithreading and memory management into the mix and I can't imagine it scaling; I'd be happy to persuaded otherwise. C++ definitely isn't the right way for me though.
@GingerGames
@GingerGames 8 лет назад
+richtw I agree with you on most parts. C is outdated but there is nothing to replace it, yet (JAI looks like it might be the one). I actually like a lot of functional programming too and how it can express data transformations in such beautiful way. It allows for a lot concurrency to happen very easily just by its nature. Concurrency and parallelism are difficult problems and not many languages take full use of it and still stick to the 1 thread approach. I don't think we need lambdas but something like locally-scoped functions. Also, `inline` should not be a suggestion in C, why is it (the compiler could warn when it is bad though)?!
@richtw
@richtw 8 лет назад
+Ginger Games Actually I guess what I'm after is not lambdas but some form of generics. std::sort is often able to outperform qsort, not just because the extra indirection through the function pointer is removed, but more because the compiler is able to optimize the code much better by inlining the comparison predicate in the context of the calling code. Any new language would have to offer some facility to generate this kind of code, be it through some kind of metaprogramming paradigm or something narrower. Of course you can even do it in C with macro hackery, but that's eye-bleedingly ugly. Most compilers have some way to specify that a function is forced inline. But I guess, just like 'register' before it, 'inline' is a code generation detail which the compiler should be ultimately at liberty to implement as it pleases. I think we probably shouldn't pretend to know better than modern compilers! I'll have a look at JAI one of these days when I have some more time - sounds interesting!
@GingerGames
@GingerGames 8 лет назад
richtw You can make a preprocessor for your C program that generates all the metaprogramming stuff but it that is another build stage and makes this a newish style language.
@richtw
@richtw 8 лет назад
+Ginger Games Yeah, this is Casey Muratori's approach, but I've never really been convinced by his assertion that this is somehow 'easier' than C++'s template syntax. More versatile, for sure, but far less straightforward. Ideally I'd want an expressive syntax within the language itself for doing this, even some kind of glorified macro with awareness of types and the language rules. What is JAI's approach to meta-programming (Google doesn't return anything)?
@GingerGames
@GingerGames 8 лет назад
richtw In JAI, you can run any code at compile time! This is much better than macros and templates as it _is_ the same language. ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-UTqZNujQOlA.html Also you access the AST within the code and modify it! ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-OHZwYYW9koI.html
@AinurEru
@AinurEru 4 года назад
@gingetBill Yes, exceptions are a bad idea, but you have't adressed the problem they were designed to solve - at all. Big software has layers of delegation, and sometimes errors occur at layers that can't handle them properly, because what "properly" means depends on knowledge that only exists in the call-sight, some unknown-number of layers above. You haven't discussed that at all. Error can also mean "wrong user input at some higher user interface layer". That may not appear very common to anyone that primarilly focuses on lower-level systems, but for everybody else, it's VERY common. Exceptions were designed as a mechanism for passing-back the error to "whoever wants to know" up the layer stack. It's not "just" about skipping code(!). Without exception the error needs to be "manually" propagated all the way up the layers, and checked at each one. THAT's the problem that exceptions were designed to solve. Whether that solution is the best one or not, is a separate discussion (and I agree that there are supperior ones), but you should at the very least get the "definition of the propblem" properly, first.
@GingerGames
@GingerGames 4 года назад
Hello. I didn't go that much into depth with the problems with exceptions in this video, especially since it was a short rant. I do expand a little a more with my issues with "exceptions" in an article I wrote here: www.gingerbill.org/article/2018/09/05/exceptions-and-why-odin-will-never-have-them/ But there are two aspects to "exceptions": Error values and Error Propagation. In this comment, you are discussing the problem of error propagation, which is what exceptions are trying to solve. Theoretically, exceptions could be just propagated through returning a value, but in virtually all implementations, they use more complex stack unwinding, which makes them a lot slower than returning a value. In practice, people do use exceptions for "skipping code" too as a form of control flow (not a good idea), not just exceptional error handling. This is usually due to a lack of structure programming features in the language. In my article I posted above, my complaint is with error propagation _across_ library boundaries, not within a library. You are totally correct that errors can propagate (I am not denying this nor is anyone) and you need to signal up the call stack somehow. There are two other approaches that can be used to solve this: encode the "error value" in the return value (discriminated union) or multiple/extra return values. C++ does not allow for either of these natively nor in a nice fashion (std::variant and std::tuple are not at all decent solutions). Another problem with most implementations of exceptions are that all error values derive from a base error value kind, which means that all error values can degenerate into this value, thus loosing all the information about that error value unless explicitly asked for (however that is approached). This looses a lot of information about what the error value contains. This also encourages lazy error handling by just passing it up the stack for "someone else to handle". This is sometimes a valid case, but in practice, most people just don't handle errors at the lowest level that they need to be handled, nor handled correctly (usually in boolean fashion). About half a year after I made this video, I created my own programming language to solve the problems I have. The programming language named Odin. For me, it has been a very successful for solving the problems I have, and for many others too. In Odin, allow the user to handle error values and propagation through multiple return values and through the type system (discriminated unions, enums, structs, etc). However, Odin does not have a concept of a built-in "error type"; this is because errors are nothing specially and ought to be handled like any other piece of code.
@AinurEru
@AinurEru 4 года назад
@@GingerGames I've started going through your demos of Odin. Impressive stuff, very similar to .jai. I've also started looking into Zig, and Beef. I am no fan of C++, not by a long shot. Unfortunately it's the de-facto standard expected to be used in so many industries, so I have to know it well and use it effectively. About exceptions, you seem to be loose on conflating it's fundamental issues with it's improper use. That's not advisable, nor fair. Every feature can be missused, causeing problems as a result of that. As you must know, degenerating exception types intentinally is a form of missuse of exceptions, or a fault in the program - not a fundamental design flaw of exceptions themselves. So is using the mechanism of exceptions for non-exceptional scenarios. Some people subscribe to that philosophy of "better to ask forgiveness than permission", I personally don't. You also haven't seemed to have considered that using exceptions is often "cheaper" than returning errors up the stack and checking them. It's only more expensive when there's an actual exception being thrown, which should be the less frequent/probable case. So exceptions optimize for the %90+ precent case at marginal cost, while sacrifycing on performance at the rare cases. From that perspective they're making the proper trade-off (counter to what you're implying). Propagating errors by returning them can be properly considered a "pessimization" of the code, compared to exception - as it optimizes for the rare case at the cost of the common case being slower. The problems of exceptions are not actually that though, it's all the other sacrifices that go along with them, loosing on simplicity, clarity and predictability of control flow. A third aspect of exceptions you haven't mentioned here is stack-unwinding. RAII was designed in part to adress the problems that exceptions created. But you could imagine a language with exceptions but no RAII, using "deffer" (I think Go does that). BTW: C++ now has std::optional which can be used instead of exceptions as a return type. It's deffinitly not super elegant, but is something the language may be able to build on. Zig's way of handling errors with optionals is built-into the language itself, and I think is the best design I've seen yet of doing that.
@AinurEru
@AinurEru 4 года назад
@@GingerGames Also, saying that "code should handle it's own errors internally" sounds to me like "code should not propagate the fact that an error occured up the stack" - which is a very bad philosophy to have - you're basically saying that errors should be silenced at their source. So if something didn't work, you don't want the callers to know about it... That's the worst kind of bugs to debug. Errors should be loud and hard, not sileced at the source. And that's still true across API boundaries. Errors should carry with them the entire stack trace from where they happened all the way up to where they are handled. With or without exceptions(!) Within and across API boundaries(!) Any other way of thinking about it is just asking for bugs that are very expensive and hard to debug.
@GingerGames
@GingerGames 4 года назад
@@AinurEru I actually disagree with you that that is a misuse. It's the natural consequence of the rules of the semantic grammar, and people naturally fall into doing that. I __cannot__ separate how something is used in real life and just saying "that person is just doing it wrong". If this mistake happens a lot, it's rarely by accident. It is also a fundamental design flaw because there is no other way to implement such an type-system-based exception-based error value. You must have a degenerative type. I'd love to be proven wrong, but I don't see any other solution to this. In my opinion, Zig is the best language that does "exception-like errors" correctly. I am friends with Andrew Kelley the create of Zig, but I do not agree with the philosophy of Zig whatsoever, and thus why I don't use it, and why I still work on Odin. I know exceptions can be "cheaper" in certain cases, and many of the benchmarks showing that are quite artificial and ignore things like RAII (if it is C++) and other scope based requirements. But to make my point extremely clear, I think there is a huge difference between handling error cases in your program and values representing the information in an error e.g. error values/types vs control structures. I did mention stack-unwinding, by the way. The problem is that C++'s RAII actually requires exceptions because ctors and dtors cannot return error values. They don't solve the problems, they actually make them worse. This is why in Odin I have `defer` instead, and all data structures are "dumb". And I stated above, C++ can allow for error values through the type system, with either a union or tuples. A `std::optional` is a discriminated union with only one variant. std::variant is a discriminated union of many variants. Odin supports both concepts, and can do it that way. Odin also support proper multiple return values too, which allows you to not bake the error value into the normal value, which is very useful in many cases, but it is not the only case. Odin's "maybe"/"option" type is created through the standard type system: Maybe :: union(T: typeid) #maybe {T}; x: Maybe(int); x = 123; if v, ok := x.?; ok { ... } // syntactic sugar
@AinurEru
@AinurEru 4 года назад
​@@GingerGames Exceptions being types is not an excuse for degenerating them. What I meant by "missuse" is catching a more general (degenerative) form than the one that was raised - out of laziness.. You can always just catch the most basic exception type, it doesn't mean you should... That's what I meant by "missuse". I didn't say that exception solve RAII, I said the opposite: RAII solves a problem caused by exceptions. The same way that "deffer" does, only more "implicitly". Performance wise, again - exceptions are more expensive than returned errors in the "exceptiona" case (when thrown), but less expensive then them in the non-exceptional case, and that IS a proper trade-off (as in, it's "optimistic"). The cost of ALWAYS returning errors is not just the machinary of returning - is much more in having to check the errors at every layer in the stack. The higher the software layer, the more "kinds" of errors can be returned, and so more would need to be handled. In a very large code-base this can combinatorically explode, and so becomes impractical. There are ways to adress this, but one way is to coallece multiple types of errors, and return a new higher-level one. Is the same as catching many kinds of exceptions and raising a higher-level one (more "degenerate" if you will, but not due to laziness, and without imformation loss). What in the philosophy of Zig do you fundamentally disslike?
@bpunsky
@bpunsky 8 лет назад
Maybe you should take the extra step, and do a tutorial series on compiler programming, building your own language along the way. Coding a compiler is actually much easier than you might imagine, but there are very few accessible resources out there on doing so. Some ideas for your consideration: Step 1) Define your language, ideally as a context-free grammar. Step 2) Create an AST framework capable of representing your language, with different nodes for each production. Step 3) Build a lexer/tokenizer and parser that transform your raw source code into an AST. Step 4) Finish the compiler with a code generator that transforms the AST into target code. The lexer/tokenizer is dead simple, and you can probably get that built in one video. Parser, two or three more. The target code could simply be C++ to start with, which would be easy to implement, and if you were to target LLVM IR you could use Clang to compile to machine code. Or you could get fancy and create a virtual machine with its own byte code, and generate that byte code. To keep things simple in my own project, I had the AST nodes double as tokens. So, the lexer generates AST nodes from the source code, and the parser assembles them into a tree structure. I'd start with a simple language, small in scope, so that you can show more up front. Once everything is working and you can compile, then you could start expanding and adding new features.
@GingerGames
@GingerGames 8 лет назад
+bpunsky I have thought about this but at the moment, I will keep to my current series. I may do something like this in the future though.
@gareginasatryan6761
@gareginasatryan6761 4 года назад
So after so many years the compsci consensus is that you don’t want an OOP for systems programming anyway and everyone just uses C for that domain. And that’s the entire conundrum. If you’re writing an end user app like Quickbooks, you really don’t want low level, “close to hardware” facilities of C++ anyway. But the whole point of C++ was the OOP and C marriage. So we are back to square one. If MS had to start now, they would happily write MS Office in C#, but the whole globe is using codebases already in C++, so we are stuck.
@swapode
@swapode 4 года назад
I disagree. I don't want OOP as the default anywhere - on the other hand I want a way to easily opt-in to some subset of OOP features in places where they are actually useful. I absolutely want a low-level language that allows me to reason well about what the CPU/Memory situation will be - and I find the mentality that some kind of high abstraction/virtual machine/whatever will do absolutely disgusting. Of course I don't want to be constantly one typo away from potential catastrophy (it's a "fun" game to come up with C/C++ examples where one letter will make the difference between a program that works exactly as expected and one that spells destruction). Luckily there's Rust now.
@FyberOptic
@FyberOptic 8 лет назад
I cut my teeth on Basic and Qbasic as a kid, moved to Turbo Pascal for a few years as a teen, then finally to C and C++ by the time I hit my late teens/20s. I spent a large portion of my adult life with the C languages, thinking that's just what programming was. There were various other languages in there too, mind you, from assembly to Javascript, but C/C++ was still the go-to language for actual applications. But when circumstances eventually thrust me into Java, the difference on efficiency was mindblowing. You go from fighting a compiler and cryptic errors on a regular basis in C++ to simply dealing with your own occasional mistakes or lack of imagination in Java. Making one mistake doesn't cause the compiler to shit itself with a hundred errors to sort through. Your Java IDE quickly and immediately shows you the source of a problem as you work due to real-time compilation and you fix it in a matter of seconds. The package-oriented nature of Java also makes it naturally more organized and easier to manage. Code hot-swapping lets to alter code while your application is running to quickly perfect something. You can refactor a field/method/class name in a large project with almost zero chance of it screwing up, where as Visual Studio rarely works properly. You can properly search for all references to something and it intelligently does so, where as Visual Studio shows you anything with that name regardless of whether it's relevant. The Eclipse/Idea/etc equivalent of Intellisense is order of magnitudes better than Visual Studio. And that's the thing. There are three or four mainstream Java IDEs which all work very well. The industry standard for C++, however, is Visual Studio, locked to a specific platform, is large and sluggish, and has all the problems mentioned above and then some. Eclipse has a C++ plugin, sure, but it's still not great. And heaven help you if you want to use code in VC++ that was created for GCC, or vice-versa. Basically, C++ can be infuriating to work with, even more so after you use something like Java and then have to go back again. Applications are just becoming so complex now. I feel that there comes a point where if you're heavily abstracting your code to avoid having runtime and development issues, you might as well try a language which does some of that for you. The performance in the long term is probably not going to be that different, but your development experience might be much more enjoyable, and the likelihood of bugs goes down dramatically. I still want to properly try C# sometime. I believe that it can possibly be obfuscated better than Java, which due to its nature makes it much easier to decompile and reverse-engineer than C/C++, which isn't good if you're making commercial software. But there's still a lot of things about Java's nature that I enjoy which even C# doesn't do, so it'll really have to blow me away to convince me to switch. That, and the development IDEs are going to have to be really darn good. Java has spoiled me, and I don't care to admit it.
@broken_abi6973
@broken_abi6973 7 лет назад
I agree that the curve to learn C++ is steep, but when I finally got it and understood it is not just "C with classes", I never felt the need for a GC or Java verbosity in my life. No seg faults, ever.
@tack3132
@tack3132 6 лет назад
C# is a slimmed down and a much cleaner version of C++, and it's just plain faster than Java... but, the only downside of it is it cannot go low to the metal. In fact, it cannot go lower than the CLI...
@patham9
@patham9 5 лет назад
@@tack3132 That C# is "plain faster" than Java was only a myth so far. Speed-wise they were never far apart, and in fact JVM speed was slightly ahead until recently. With the DotNetCore releases the situation has improved for C# though. Except for programs that run 24/7. For these, JVM is still better due to its clearly superior JIT that takes runtime stats into account. For current Benchmarks see benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/csharp.html but keep in mind that these only run for a few seconds, and that after hours of runtime, about 40% speedup can be expected from Hotspot JIT (while 0% speedup for .NET jit as it does not further optimize after its first invocation). But these speedups do not always result, additionally consumer programs do not run for a long time usually, so now, which one is faster is even more tricky and cannot be said in general. I personally wish a Hotspot-like JIT would make it into DotNetCore, then we would have both, a cleaner language and the best JIT in the world. Hotspot has come a long way.
@megetmorsomt
@megetmorsomt 2 года назад
The "History" of C++ is factually wrong: For his ph.d thesis Bjarne Stroustrup needed to simulate distributed systems and tried writing the simulator in Simula. He found Simula perfect for the job except that it was much much too slow for his purposes, and he had to write it in BCPL instead - which he found was a nightmare. Facing a similar problem at Bell Labs he thought to marry C with the classes of Simula since he had C's creators right at hand, and C was blindingly fast. So as you can now surely see: he had his reasons to do what he did...
@GingerGames
@GingerGames 2 года назад
How is what I said wrong? You've just given the larger story to it, of which is not contradicting what I said, per se. He did have his reasons, but I don't necessarily think that those reasons were technically needed to complete his PhD either. Why not write a better Simula compiler?
@megetmorsomt
@megetmorsomt 2 года назад
@@GingerGames I don't think the guy is obligated to solve his problems your way - nor is anybody else for that matter. C++ has clearly served well: so maybe he was not as wrong as you make it sound. You state that he didn't really have a reason - I have shown that he did...
@GingerGames
@GingerGames 2 года назад
@@megetmorsomt I was never implying he should follow my logic retroactively with a time machine. But think through his problem, would you have done that? If a language was ideal for your problem, but the compiler you used wasn't that great, what would you do?
@GingerGames
@GingerGames 2 года назад
@@megetmorsomt and secondly, why are you taking a literal rant as if it is a well written serious argument?
@megetmorsomt
@megetmorsomt 2 года назад
​@@GingerGames Maybe I thought Bjarne deserved better than what you gave him. Whatever you think a rant is, it's not to anybodies benefit to misrepresent history - I merely corrected a false impression.
@embeddor2230
@embeddor2230 2 года назад
1:15 Templates are used for far more things than just arrays and hashtables. What about lambdas, module configuration parameters, compile-time constant parameters, generic wrappers, type traits, perfect forwarding, type aware containers, type aware allocators, meta programming, generic matricies for math and linear algebra, etc. If one doesn't find templates usefull, that's clearly because they haven't done enough efficient generic programming.
@GingerGames
@GingerGames 2 года назад
Lambdas, configuration parameters, compile-time constant parameters, etc None of those specific things require templates in a new language. That's just how they work in C++. And in practice, the only ACCEPTABLE use of templates is for containers, and most uses outside of that are usually bananacakes and should be avoided always. n.b. if you didn't know, I went made my own language instead because of how fed up of C++ I was---the Odin Programming Language.
@embeddor2230
@embeddor2230 2 года назад
@@GingerGames I think, every feature of C++ has a reason to exist and solves a specific problem. One might not know that and regard the feature as bloat just because they never had to use it in their projects or because a workaround already exists. Like lambdas vs function pointers, exceptions vs setjmp, manual memory management vs RAII, etc. But I get your point. If you are going to design a new language, of course you can avoid all the pitfalls and accidental complexity of C++, and come up with a "better" language.
@GingerGames
@GingerGames 2 года назад
@@embeddor2230 It' s all about trade-offs and costs. Having a "reason to exist" doesn't mean it is good one, nor worth the cost. For instance the main reason exceptions exist in C++ is to allow to handle failure states within ctors/dtors. There's a reason it's common to see from veteran C++ programmers (not Modern C++ programmers) to see explicit `init` and `destroy` methods.
@embeddor2230
@embeddor2230 2 года назад
@@GingerGames Exceptions aren't just for handling errors on constructors, they are also useful for avoiding the branch cost each time you call a function. For example, in my field, embedded systems, some times the clock of the cpu is very close to the clock of a serial interface, so that the cpu must keeping writing to that serial interface with minimal delay due to error checking, in order to make the serial interface work at its maximum speed. In such scenarios, I either use setjmp or exceptions to avoid the branch cost from each functional abstraction layer till the caller function. And I guess you agree with me that setjmp is very unsafe compared to exceptions. See, that's what I meant earlier, some programmers might not need/use a feature in their fields, but that doesn't make it bloat or useless. Of course exceptions could have been implemented in a better way, but they are there to solve a problem people in some areas are facing.
@GingerGames
@GingerGames 2 года назад
are never a good idea. I'm not a fan of exceptions in any context, but if they are needed, setjmp is fine, or even just using computed `goto` if the compiler supports them. I recommend this Podcast episode with me in it to get a better view of my view on exceptions: media.handmade-seattle.com/the-race-to-replace-c-and-cpp-2/
@ChrisAthanas
@ChrisAthanas 28 дней назад
I’m enjoying the Kotlin everywhere with KMP
@SystemSigma_
@SystemSigma_ 2 месяца назад
Metaprogramming is the worst thing people abuse in C++, on top of creating abstractions over abstractions just to feel smarter than you for no reason.
@LemonChieff
@LemonChieff 5 лет назад
I love C++. I learned C first then started to use C++… Thing is you don't have to use any C++ feature. Everything you do not use comes with no overhead. But they have 2 objects that are indispensable std::vector and std::string then if you want your program to be optimised you use the -O2 compiler flag. Oh also you get ranged-for ie `std::vector v; /*...*/ for (std::string n: v) printf("%s", n.c_str());` If you don't want exceptions (and god knows I hate them) don't use them. If your code is well written you won't get any exception.
@hymen0callis
@hymen0callis 8 лет назад
In C++, there's the _SCOPE_EXIT_ macro made popular by Andrei Alexandrescu or _Boost::ScopeExit_, which do basically the same as _defer()_. I'd prefer a built-in keyword like that though. Admittedly, I've never been a C programmer and I'd never want to program in C when I can also do it in C++. C++ (done right) is *so* much more elegant [1], sophisticated and capable in my opinion. The sad thing is, there's too much backwards compatibility in the language and many newer language features aren't yet implemented by some compilers (MSVC), and there's also that _consistency_ problem you're alluding to in the rant: too many ways to do the same thing. [1] Of course, this is a matter of personal preference.
@GingerGames
@GingerGames 8 лет назад
+hymen0callis That is what I do in my projects. `SCOPE_EXIT` is very similar to my `defer` macro. C++ can be cleaner but not that much compared to clean C code.
@nexusclarum8000
@nexusclarum8000 5 лет назад
If you're good at naming your functions and variables... use good casing... and proper spacing. Stick to good programming practices like keeping functions less than 25 or 30 lines long I'd say C is 100% just as readable as C++. Oddly enough even though higher level languages are meant to help you make things more modular you'll be more tempted to have monolithic functions/methods in them.
@scvnthorpe__
@scvnthorpe__ 2 года назад
I'm a real sucker for Rust but I am venturing into C as well. Don't think I'll be touching C++ if I don't have to
@MrAbrazildo
@MrAbrazildo 2 года назад
14:10, if 't' will end at the end of the f() it was created, fine. But what about if it'll be returned, to continue its existence elsewhere? It's better to have it hidden in a class, to dictate how and who can manage its resource. 17:10, in embedded systems or any performance apt., in which you are struggling to fit all data into L1 cache (fastest), you won't have the luxury of having an entire other array to put the output. So, you should make the sort inside itself - allocating would be too slow. And the C-qsort is a bit low level, since that 'void *' can be anything, wrongly mistaken by another type. In C++ templates you can just send 2 iterators, that will advance according to its type, so there won't be any chance for a mistake about that. And they can receive no cost tags, which can compile-error if any type mistake was made. 19:35, secretly, C/C++ compilers use move as default whenever is possible, due to optimization. I heard committee member saying move semantics was a mistake. But it's okay, I don't use. You can just keep sending by copy/value. A performance downgrade can occur only in pointer/references, when the variable was small enough to be send by copy, or if it was too big and was send by copy. Is move default in Rust? Well, its efficiency will hit the wall, if it hasn't the other way.
@GingerGames
@GingerGames 2 года назад
1) I'm not a fan of RAII whatsoever and it's not better to have it hidden in a class with a dtor. I prefer the explicit `defer`. 2) I was just making an example and I could have written numerous other approaches, as well as an imply sort. And qsort isn't that low-level, it's pretty high-level but relies on type erasure to work. 3) R-value references in C++ have to be implemented in a really bizarre way which can cause huge issues in terms of performance. A good example would be `int &&` being passed to a procedure as a pointer because of the required semantics.
@GegoXaren
@GegoXaren 4 года назад
Standard C has Generic Selection macro. Use it. And use GLib/GTK style namespacing and you should be golden.
@ShiroAisu10
@ShiroAisu10 5 лет назад
Late to the party, but you couldn't add function overloading without name mangling, I don't think.
@MrAbrazildo
@MrAbrazildo 2 года назад
20:00, I don't think this is actually a bad thing. It means there are plenty of resources for everyone. It's like living in a big city: nobody will use all that the city offers. It only means it's rich. And this can lead to better feedback from practice: different combinations, facing new issues, richer experience. 23:40, in C you can #define a macro, use it, and #undef it later, manually managing a "scope". But C++ has a better thing: 'constexpr' keyword, forcing the compiler to solve everything tagged so at compile time. And it's not only macro-like stuff, you can write complete f()s, runtime-style. Of course, all variables and f()s must be known at compile time. I heard C++ committee members are trying to bring this to C, because constexpr fails when evoking a C f(). 24:45, really? What? 25:13, just compile your code with C++, using some of its features.
@GingerGames
@GingerGames 2 года назад
1) Complexity and complications are bad things when you are working with numerous people on a team. Only using a dialect of the language is the problem since everyone uses their own dialect of which which doesn't intermingle well. The worst case of this would be Common Lisp where each person's code cannot interact with another person's because it's radically different. 2) The C preprocessor is purely textual and has no concept of a scope. `constexpr` is not equivalent nor better, in fact C++ had to add `consteval` to even come closer and even then that is loads of issues to it. 3) C is fundamentally broken, especially its type system. I've explained this in other videos, and why I resorted to making my own language. 4) I don't think you understand why people use strict C then rather than using a C-like subset of C++.
@astrahcat1212
@astrahcat1212 Год назад
You want a better C and it's called Holy C, but it's only on Temple OS
@thineshgen
@thineshgen Год назад
why do you prefer C89 over C11? Also Clear and direct concepts explained above.. Good work.
@MrAbrazildo
@MrAbrazildo 2 года назад
5:16, sure he was trying to solve a problem: C was unsafe, and classes serve, above all things, to encapsulate data. For highly interactive projects, such as games, this is crucial, because instead of calling f()s A, B, C, always in this order (scientific projects, for instance), they can change the order according to values from variables. Although C has its own ways to hide things, they are clunky. 5:33, isn't this the very "future of programming", the goal which all of us should be aiming? Step forwards, to a higher level, still keeping all the power. C++ seems to be the only language doing that. Other ones sacrifice things along the way, and start to stink. C and Assembly accomplish almost perfectly what they ambiciouned, but they are not "stepping to the future", they are stuck - _and should be, as they already accomplished what they were designed for_ . C++ has a neverending path. 7:42, maybe you should take a look on D language. They say theirs is a better C: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-thAV-XqAsPo.html&pp=ugMICgJwdBABGAE%3D 9:21, I completely agree to you about exceptions - and I don't use them. 11:05, they got into the language because they didn't force C++ to sacrifice anything, they are completely optional. And if any higher level thing has this kind of humble price, it should be added, to make the language even better, with plenty of options for a diversity of projects. I personally have a policy of only using slow higher level features if I can abstract them into macros, getting rid of them anytime, as an on/off switch behaviour.
@GingerGames
@GingerGames 2 года назад
Classes do encapsulate data but it still had ALL of C's safety issues still, it just added to in them in fact. The joke that even Bjarne Stroustrup uses is that C will shoot your foot off pretty easily but C++ takes more steps but will shoot your entire leg off. > C++ seems to be the only language doing that. Then you'll be happy to know that after I made this rant, I started work on a new language called Odin which is a step towards being "higher level" but have MORE power than C++ in terms of performance, memory layout, and memory allocations. > maybe you should take a look on D language. I knew about D even back when this video was made and it was a no-go for me for numerous reason (exceptions, optional GC, etc). It's one of the reasons I started my own language: Odin. C++ are only really "optional" if you don't use any features that require them, e.g. ctors or dtors must never fail.
@MrAbrazildo
@MrAbrazildo 2 года назад
@@GingerGames - Once I got used to C issues, I rarely got into trouble - _and many of them you can kind of avoid using some smart macro_ . But encapsulation is a "must have" to me - _btw, it seems only C++ does it properly_ . I rarely got more than 1 day chasing a bug. The joke about C++ is that is hard to a bug slip out from encapsulation, but sometimes they do, and are a nightmare of a bug - _a thing other languages not even imagine, they would fall far earlier_ . I got some of those. Things like a "Replace All" that joined the name with another thing, freeing an another old "sleeping bug", that was waiting the chance to get freed - 2 bugs working together! Usually all the suspects for a bug are listed in a class, leading it to be cleaned in minutes, if not seconds. - RU-vid recommended your language right at once. But I'll 1st finish watching this video, and commenting it. C++ is very resourceful; if you can improve it in any aspect, it's already worth to take a look. - D speakers say if you don't use its runtime features, it's "faster than C", according to a benchmark that was showed at the ending of that talk. - All C++ compilers have flags that turn off exceptions and RTTI (runtime) features. So ctors will never throw (even when failing), dtors will always be executed, bytecode will be much smaller, no performance lost, and so on. Plus, there's the 'noexcept' keyword, which forces turning off exceptions for f()s that have it, even if "they are on" on the compiler.
@RecycleBin0
@RecycleBin0 5 лет назад
not a well known fact: classes are sort of accessible in C by using functions and structs but you often get name mangling
@FlanPoirot
@FlanPoirot 2 года назад
that's not classes and it's a kind of well known thing, some C libs work that way (gtk). embedding functions in structs to make structs namespaces is standard practice in most modern languages by now (rust, go, zig, etc). it's a nice solution cause there's no inheritance hell and you instead have to favor composition and other technics (including plain old procedural programming)
@RockTo11
@RockTo11 8 лет назад
I think Objective-C is what C++ should have been. It's a shame it's not that portable, since most of the functionality is in the libraries. It's a clean (arguably simple) layer on top of C, with a mostly consistent syntax. I also quite like the names arguments in function calls.
@WouterStudioHD
@WouterStudioHD 4 года назад
Lol, Objective-C is awful, Poor support for inheritance, poor support for templating/generics, no namespaces. And it can't replace C in many cases, because the runtime is waaay bigger because of the message passing and garbage collection. Rust would be more appropriate.
@RockTo11
@RockTo11 4 года назад
@@WouterStudioHD I absolutely agree; 100%. I had to use OOP, because of Java at work, and I hated it. I always did what is now commonly referred to as Data Oriented Design. I like my data to be just tables (contiguous arrays). I moved to C, which I have been working in since the mid-1990s, and now use C-style C++ (C with constructors and namespaces basically). But Obj-C doesn't do garbage collection any more. Just some auto-reference count stuff.
@leonhrad
@leonhrad 8 лет назад
Good points, but to be fair, C++ really is an easy target to rant about its problems.
@GingerGames
@GingerGames 8 лет назад
+Leo S I know it is but the problem is that there isn't an alternative still. I could rant about the language and its culture for hours but I won't (I didn't even cover the standard library or STL which another problem altogether unrelated to the actual language). I want a language that is designed for modern hardware and has metaprogramming abilities that are as good, if not better, than lisp.
@WouterStudioHD
@WouterStudioHD 4 года назад
@@GingerGames Rust?
@ipotrick6686
@ipotrick6686 3 года назад
@@WouterStudioHD rusts metaprogramming is not on c++'s level. If rust gets reflection, better generics, compile time execution and good meta programming it could replace c++ for me personally.
@siddharthupadhyay6347
@siddharthupadhyay6347 3 года назад
@@ipotrick6686 True Rust's compile time is insane.
@TheBuzzSaw
@TheBuzzSaw 8 лет назад
Have you looked into JAI by Jonathan Blow?
@GingerGames
@GingerGames 8 лет назад
+TheBuzzSaw Yes I have and it is exactly what I am looking for in a language. At the moment it isn't available but I would like to use it when it is! The metaprogramming abilities are already the main selling point of the language as well as the allocator contexts, SOA/AOS struct layout, and so much more.
@TheBuzzSaw
@TheBuzzSaw 8 лет назад
+Ginger Games Woooooow. Sorry for the triple post. My phone said "Posting failed. Try again later." So I kept trying. Then I heard you mention it in the video, so I gave up on trying to post it. It sounds like RU-vid/Google could use a better programming language. XD
@yash1152
@yash1152 Год назад
hey ginger, i think u meant c++ is a frankestein in chapter marks as well
@yash1152
@yash1152 Год назад
5:49
@yash1152
@yash1152 Год назад
6:18 he (BS) started publicizing it, yeah i felt same as i have been thinking more & more about c/cpp these 6-7 days past.
@TopShelfization
@TopShelfization 4 года назад
No unix was (originally) developed in B, B didn't have types (or structs), that's why C was created.
@broken_abi6973
@broken_abi6973 7 лет назад
Regarding his criticisms of RAII and why defer is so much better: I don't like the noise it creates in the code. Still, if I want to use something other the default ctr/dtr, the language should provide that functionality, which C++ actually does. And C++ will soon provide the tools for the next examples he mentions on static duck-typing. Check "constexpr" and "concepts". No need for a new language just bc of those features.
@ipotrick6686
@ipotrick6686 3 года назад
RAII and defer together would be perfect. I definetly like RAII and i like defer, i think one shold have both at disposal
@codymccodeface2094
@codymccodeface2094 8 лет назад
It looks like you're looking for something like ark-lang.org/ it has the defer from Go, without the GC. And it keeps a lot from C. Not finished yet. As for myself, I'll stick with Rust. Ark at least seems to have a sane module as oposed to C/C++.
@GingerGames
@GingerGames 8 лет назад
+John Wayne Unfortunately, it doesn't have my metaprogramming needs. Ark looks good, it seems like an cross between C, Go, and an unsafe Rust however, it is still not that different that those. A lot of new programming languages are still minor improvements over C and other languages but with better syntax. Even though lisp is old, it's metaprogramming is still one the best things and most languages still do not do it. A small improvement over C is not something that will make me move from C/C++. What I mean by metaprogramming is being able to produce extra code using the same language that I program the program. The code itself should be data that I can read and modify. I have not seen a current language yet that does this or if it does, it is a high level interpreted language. I have thought of making my own language but the problem is that this is a huge problem to solve and I am probably still not the best person to design a language. I have made toy languages before but nothing I would use. I am looking forward to using Jonathan Blow's language, Jai. It already meets a lot of what I am wanting from a language and I cannot wait to see what happens to how it progresses.
@codymccodeface2094
@codymccodeface2094 8 лет назад
+Ginger Games Ok, as long as you're happy with it. Jai looks interesting, not sure will have the time to play with it. But new ideas for doing things are always welcome, especially from people with experience building highperformance apps like games. I'll still stick with Rust for now. I think it's very elegant for a systems language.
@broken_abi6973
@broken_abi6973 7 лет назад
Unfortunately, Rust is not that fast, regardless of what its evangelists say :/
@hyche3163
@hyche3163 8 лет назад
Sorry for my nooby question, Im learning programming. You said that the error can be handled by returning the value of the function. But if you do that way, how can you get the actually used value for other stuff not for handling error ?. Thanks for great video.
@GingerGames
@GingerGames 8 лет назад
+Hy Che What you usually do is pass the value you want by pointer. Error some_func(int *out_var, int in_var); Then all you do would be this: int out; Error err = some_func(&out, 123); The real solution to this would be multiple return types but C nor C++ support this so this is the current solution. In other languages such as Go, this is possible. Another thing to note, an error doesn't have to be just an error code, the error can have a lot more information to it about what went wrong.
@hyche3163
@hyche3163 8 лет назад
+Ginger Games Thanks for the reply. If it does that way, as far as I know there are some functions that they are not need to handle error, right ? Why is that ? Because I have used some functions in some libraries that they just return the value I want, and there are no error handlers in them include the exception.
@GingerGames
@GingerGames 8 лет назад
Because you should only return an error if there really is an error! A lot of the time, there isn't as you should be able to handle in your code.
@dertechl6628
@dertechl6628 7 лет назад
C++ *does* support multiple return values using std::pair.
@satan2583
@satan2583 6 лет назад
All the fucking code now is c++!!! what happened to command prompt, guys?!?!
@nateedwards1313
@nateedwards1313 2 года назад
Have you tried Nim? (I know 6 year old video, don't tell me how to live my life!!!)
@GingerGames
@GingerGames 2 года назад
I have tried Nim but it didn't meet my requirements. That's why I created the Odin programming language.
@nateedwards1313
@nateedwards1313 2 года назад
@@GingerGames I'm silly I didn't even realize that was you. Odin is bad ass. I don't have faith in llvm in the long run. I'm pretty sure that's the only reason I choose Nim.
@heater5979
@heater5979 4 года назад
I think you are mostly right. C was designed to solve a problem. The problem was how to make Unix portable. Although, if you check the history, Unix was originally written in assembler. C was designed later to make all the things they did in assembler portable. The problem to today is how to build code that can exploit the power of all the multiple CPU cores or even multiple machines. Neither C or C++ address this problem at all well. It's really hard to make large parallel codes in C or C++. That is the problem Rust and other languages are tackling. In that way Rust has the focus on solving a problem in the same way C did back in the day.
@tack3132
@tack3132 6 лет назад
I'd just add the classes and inheritance and encapsulation and constructors and polymorphism and the function overloading and the namespaces and the templates and the virtual and override and try and catch keywords and smart pointers. which is all I use in C++ anyway. The rests are just libraries and useless keywords to me..., but I would make the inheritance work like they do in Java and in C#, by forcing only one inheritance and forcing me to use interfaces instead of multiple classes. But other than that. I wouldn't add too much to it...
@jackwang5734
@jackwang5734 2 года назад
i agree with most of what you say but i kinda like raii, because with a nested type of non trivial destructible other type (meaning does nothing) example struct Foo { vertex_bufffer b; linked_list l; socket s;.... }; if with raii style you can just ignore everything but with defer you have to put defer { close_buffer(&instance.b); destroy_list(&instance.l); close_socket(&instance.s); } for every instance and you end up with this boiler plate every time and when you put struct Foo in some kind of contaner (example vector in c++) you have to rewrite that complex defer statement again because you cant make a generic destructor function for struct `container` without an uniform way to talk about how to defer that type (in this example `Foo`) so you end up wite your own destructor for struct Foo and defer every instance of Foo wich done automatic by raii; with the example about file i think it's just much better to write a function that open a file but NOT return a file but return a Optional type wich is the way rust does (i dont know why c++ doesnt) in this way you are force to handle the error when open a file before you can even use the FIle_handle type and i totally agree with you about EH wich is kinda wrong(not in GC language wich not C++) and a lot's of thing in C++ really get overhype with oop wich i dont like. I thing if they remove oop stuff( virtual, inheritance, EH) new and delete , the initialize () and implicit cast, and add better compile time check for template param or maybe nerf it (template is too powerfull wich lead to abuse, it even posible to write a format print function that take an string literral as an template agrument :D), destructive move semantic and better build system in the begining (1990 ?) i think it's will be a pretty enjoyable language in my opinion :)
@GingerGames
@GingerGames 2 года назад
Regarding your reply: instance := foo_create() defer foo_destroy(&instance) This requires no more code to write than an explicit ctor/dtor in C++, with the only exception is the explicit initialization and destruction (effectively 1 line more of code). The language that I created, Odin, was the result of my frustrations with C & C++. It supports both multiple return values and Maybe types. So all of the following are possible in theory: open :: proc(path: string) -> (fd: Handle, err: Error) {...} open :: proc(path: string) -> Maybe(Handle) {...} // less useful because you don't know why it didn't open open :: proc(path: string) -> Result(Handle, Error) {...} // Result would be a user-defined type Regarding your last point, you might find Odin is a very enjoyable language to program in! It removes all OOP stuff (no methods) but allows you to do it in a much more controllable manner than even the best OOP languages (through the use of Odin's `using` and the `->` operator). Odin also support parametric polymorphism (akin to templates in C++) but in a much simpler and cleaner approach than C++.
@jackwang5734
@jackwang5734 2 года назад
i dont think all oop stuff are bad :/ method is very fine for me it let you explicit say about how your data structure work to fit in some kind of interface and i like return multiple value and not tuple style (anonymous struct with anonymous field name) but with explicit field name style well.... i think in the begin template is simple, just compiler copy paste your code but then people get creative and when they got too creative template get really bad really quickly and really bloated the binary ( templated variable to define type trait, templated undefined struct and function to allow overloadable interface..., templated lambda to make compiler can inlined it ) I think a lot's of C++ feature follow that pattern, it let you full control and very powerful but when you control it not well it all up to you to handle the mess you make wich is sad
@ipotrick6686
@ipotrick6686 3 года назад
you would like c++20 modules and constexpr additions. c++17 also increased template metaprogramming readability massivley with fold expressions, i could clean up so much code with them
@GingerGames
@GingerGames 3 года назад
I actually absolutely hate them :P
@ipotrick6686
@ipotrick6686 3 года назад
@@GingerGames they are very ugly
@GingerGames
@GingerGames 3 года назад
@@ipotrick6686 It's not the ugliness of the syntax but the semantics that I dislike.
@patham9
@patham9 5 лет назад
++C-related: function overloading
@ipotrick6686
@ipotrick6686 3 года назад
i heavily disagree on the first two, would argue the exact opposite for point 2
@patham9
@patham9 3 года назад
@@ipotrick6686 Also understandable. Design decisions in programming languages are highly subjective. Some of my dislikes come from having seen crazy stuff like socket connections hidden in a "-" operator overload. I have also seen messy C code, but at least there I know what the machine is doing at each point, without having to dig into other places of the program.
@ipotrick6686
@ipotrick6686 3 года назад
@@patham9 socket connections hidden in a"-" operator overload. Oh man code review should be very angry lol
@ipotrick6686
@ipotrick6686 3 года назад
@@patham9 and i would agrue that overloading operators in a convusing was is thae same problem as not naming your functions good names you know. If you do thast right you wont abuse operator overloading
@patham9
@patham9 3 года назад
@@ipotrick6686 I could almost agree, but often if you have a more complex object the meaning of, say, "*" will seldomly be self-explanatory. This is even true for relatively simple mathematical constructs where different kinds of products exist and for instance a distinction between matrix multiplication and element-wise multiplication needs to be made. It's even more problematic when usual properties of * (commutativity, associativity, ...) do not hold, which is a good way to hide bugs. I agree to the importance of self-explanatory naming though, and would totally support being able to write mul(a,b) with an infix format "a mul b", but assigning different meanings to + - * and / beyond the meaning of numerical types like integers and floats? I'm not convinced.
@johanot
@johanot 6 лет назад
err := doStuff1(); if err != nil { invoke_err_handler(err); return; } err = doStuff2(); if err != nil { invoke_err_handler(err); return; } err = doStuff3(); if err != nil { invoke_err_handler(err); return; } err = doStuff4(); if err != nil { invoke_err_handler(err); return; } err = doStuff5(); if err != nil { invoke_err_handler(err); return; } .. above could be replaced with: try { doStuff1(); doStuff2(); doStuff3(); doStuff4(); doStuff5(); } catch (err) { invoke_err_handler(err); } In case you are wondering why exceptions are nice to have ;-)
@GingerGames
@GingerGames 6 лет назад
Johan Thomsen and that is exactly why I hate them.
@johanot
@johanot 6 лет назад
Can you explain why, other than "i just hate them"? I personally prefer the 10 line version rather than the 30 lines of copy-pasted conditional blocks. That's just useless. Not saying I'd use exceptions for everything, just saying that the Golang error handling pattern is nauseating to me. :) Exceptions aside, would prefer to just pass in a callback reference to my error handler function.
@GingerGames
@GingerGames 6 лет назад
Because an if statement lowers down to a branch whilst an exception requires unwinding the stack. The former is much cheaper than the latter. I want things to be explicit and to know what is through an error and when. I want predictability. I do not want errors to be anything special. Error handling should be treated like any other piece of logic. Error values are just values.
@johanot
@johanot 6 лет назад
Your first argument has more to do with mem management and destructors and how C++ handles throw, than to the actual language pattern of exceptions. Whether it's cheaper comes down to concrete application and implementation rather than the pure concept of exceptions itself. I don't write C++ myself btw. Say you could combine defer { } and throw and disable auto-unwind ? It sounds like what you don't like is the automatic nature of the C++ implemetation. I agree very much with your second argument. "exceptional state" is an opinionated term. Although there would be much fewer headaches if we didn't have to do IOs all the time.. Hehe. But this argument should/would actually make you hate the infamous useless Error-struct of Golang?
@GingerGames
@GingerGames 6 лет назад
Firstly, no it doesn't. The scoping behaviour has nothing to do with my issue with software exception. Unwinding the stack is not cheap. A branch is. Branches are predictable and a constant cost, whilst an exception will only happen when it throws which is not consistent.. As for Golang's `error` interface, I actually use my own custom errors all the time that contain extra information and so that I can `switch :=` on them so they act like a series of catch blocks but with a completely different control flow.
@SoulofAnotherDeity
@SoulofAnotherDeity 8 лет назад
My suggestions to improve C: - Optional return types for functions. If it doesn't have a return type, it's void. - The '.' operator should dereference pointers. No excuse for '->'. - A function with a pointer-type argument should automatically reference a non-pointer object. No excuse for & everywhere. - Add in C++11-style for-each blocks `eg. for (arg : args) { ... }` - Simplify the terminology a bit so you don't have to type as much. switch->on, break->exit, continue->next. This seems like an odd suggestion, but you'd be surprised just how good it looks. - Allow the ability to continue or break out of loops by the name of their iterator. - Add a transparent string data type. - Allow symbol capturing on functions and blocks of code. eg. `int open(str path, int mode, int perms) [errno] { ... return 0; }` - Rewrite the entire api. For the love of all that is holy in this world, get rid of that abomination and standardize the things that literally everyone uses these days (threads, audio, graphics, input, localization, big numbers, etc.) I'm absolutely fed up with having to write wrappers around 4 or 5 platform-specific api's every time I want to write a portable application. - Add the ability to compare with, assign to, or iterate across slices of arrays or strings. It's like an incredibly terse and OP implementation of strncmp and strncpy. - Operator and function overloading - Namespaces/modules/packages - Standardize anonymous enums, structs, and unions. Seriously. - Declaring an enum, struct, or union should declare the type of it as well. Only imbeciles (read "POSIX") are dumb enough to think that people like typing 'enum', 'struct', and 'union' everywhere. - Don't let enums pollute the global namespace unless they're anonymous. And if structs or unions are anonymous, pollute the hell out of it. My intentions are clear. - How about a 'countof' operator that does the equivalent of `sizeof(x) / sizeof(*x)`? - Screw the last idea, why not get rid of all *of operators and have meta-attributes? `x\size; x\type; x\count; etc.`.
@GingerGames
@GingerGames 8 лет назад
- C's syntax doesn't allow for it (unfortunately) - I completely agree - I want something even better than that! for (index, value : array) { ... } And more! (Look at what Go does, it's close to what I want) - I do like to be explicit and writing &var is not really a problem for me. I want to know I'm passing something by pointer from just reading the code. - Not really much of a difference but okay. - I do like that but goto does exist and "can do this". But named loops is a better solution. - We need a string that isn't null terminated! I have one in my libraries. - Maybe (but not the example you gave, I hate errno). - Already doing that github.com/gingerBill/gb - Not that sure what you mean by that. - Maybe not in C (as C is meant to be simple). - Definitely modules/packages, maybe not namespaces (like C++ at least). - Yes (and that's the case in C11, I think) - I agree but it would break too much legacy code (and some people (for some reason) really like struct Thing, enum That). - Enums should be called by the type e.g. ThingType.Value and enums should have a string version of the value too. - I already have count_of, size_of, align_of, etc. in my code (see above library) - That might be okay but it's not really very C-like. Personally, I think I want a new language, but there isn't one out there to replace C/C++ (not even Rust or Go or whatever)! I also, want tagged unions, better metaprogramming capabilities, multiple returns, introspection for struct/enum/union/etc. and more.
@SoulofAnotherDeity
@SoulofAnotherDeity 8 лет назад
Ginger Games likewise. the syntax I've been somewhat leaning towards is something along the lines of: using files; main(args) { opt = 0; fname = ""; for (arg : args[1..]) { if (arg[..2] == "--") { if (arg[2..] == "input") { opt = 1; next arg; } print("error: invalid argument '%s' " % arg); return 1; } else on (opt) { case 1: fname = arg; opt = 0; next arg; default: print("file '%s '" % arg); } } for (line : open(fname, readOnly)) print(line); return 0; } where all variables are variant-typed unless explicitly stated otherwise (meaning that they carry their own type information at runtime). Really, what I'm concerned with are concurrency, performance, portability, terseness, and legibility.
@chastitywhiterose
@chastitywhiterose 4 года назад
"- Rewrite the entire api. For the love of all that is holy in this world, get rid of that abomination and standardize the things that literally everyone uses these days (threads, audio, graphics, input, localization, big numbers, etc.) I'm absolutely fed up with having to write wrappers around 4 or 5 platform-specific api's every time I want to write a portable application." I agree with this. It's not possible to make a standard game in either C or C++ without requiring en external library like SDL,Allegro,SFML,Windows API, etc. The ability to make a game that responds to user keypresses and draws things on the screen was something that other languages usually made part of the standard library. Even QBasic my first programming language I learned could do those things.
@origamibulldoser1618
@origamibulldoser1618 8 лет назад
Passing error codes down 20 levels of stack rather than throwing is a good idea?
@GingerGames
@GingerGames 8 лет назад
If you have 20 level deep callstack, you've got bigger problems than error handling. Error codes should be handled by no more than 2 levels deep as you should handle the error there and then. This is what I prefer and was saying in the video.
@origamibulldoser1618
@origamibulldoser1618 8 лет назад
Well, consider some kernel-like part of the code that needs to know whether or not some function call it dispatched went okay. That call may be arbitrarily complex, right? I think you're dodging my point here with a "No True Scotsman" argument. But that particular thing aside, I agree with your general sentiment about C++. The more I think about it, the less I want to do OOP. On the positive side of C++11 and beyond, I think std::thread and std::mutex were an excellent addition. It's convenience, but definitely time saving features.
@GingerGames
@GingerGames 8 лет назад
***** In that case, error codes and exceptions are not the way I personally would solve it, that's a problem with a certain solution. I am not saying error codes are the only way to handle errors. In fact sometimes, an error type would be preferable to get more information or even an error system (queue/stack/etc. Based). This is a huge topic to discuss but exceptions are _not_ the best to handle errors, even in that situation. Having 20 levels deep is tricky (not as bad as some Java stuff with over 100 calls deep) and in those cases, a certain solution is needed, maybe a more deterministic handmade exception-style system but definitely not the C++ one. I think the problem with C (and C++ for that matter) is the lack of a decent standard library. If there were decent stdlibs for C, it would easily be a very useful language by default. C++11 does have some nice stdlib features but there are a lot bad ones too (even if they implemented, they are designed badly).
@nexusclarum8000
@nexusclarum8000 5 лет назад
If you write good code it'll be pretty readable and usable in any language.
@gammyhorse
@gammyhorse 11 месяцев назад
The language you're looking for exists. It's called Object Pascal.
@GingerGames
@GingerGames 11 месяцев назад
This video is very old, and I've already got my language: Odin.
@Dziaji
@Dziaji 5 лет назад
C++ 11 is the best language. The only downside is the learning curve if you are used to languages that baby you and hold your hand. Once you learn how to properly use C++, you need to write some overhead code to tailor it to your purposes, but the application code will be highly readable and unimaginably efficient with respect to cpu and memory. No ither languages come close.
@Elite7555
@Elite7555 5 лет назад
Non-descriptive error codes are a bad way to go, especially if you forgot checking one. That can even lead to some serious security breaches, and it has. Always use fatal exceptions when the system has reached a non recoverable or undefined state. A stack trace makes debugging much easier. And when you write libraries, most of the time you can't deal with errors. With error codes it is very easy to just swallow errors. Now the caller is screwed. All you can do as a good library author is to forward errors to the caller. Not only makes that library design ugly, but what is the caller going to do with all those errors? He can't deal with most errors either or just doesn't want to because it isn't critical for his work. Or he wants to deal with errors in one central place. That is what web frameworks or the likes try to achieve and it makes logging much easier. And I am not even going after defer. RAII has proven it's worth and GC languages like C#, Java or Python have adopted the pattern with resource scopes.
@nIghtorius
@nIghtorius 11 месяцев назад
You do know C++ has scopes? If you allocate a object/thing in the stack during a scope and when the scope ends the objects gets also destroyed. You aware of this? ex: #include using namespace std; class Thing { public: Thing() { cout
@GingerGames
@GingerGames 11 месяцев назад
I am very well aware of RAII, but as I say in that video IIRC, you cannot do any error handling when in a ctor/dtor. That's why I use/used a defer construct instead and to explicit (but scope-exit controlled) init/destroy calls. If something goes wrong in a ctor/dtor, you pretty much need to use exceptions which I forbid using. If you search for defer in C++, my article is probably one of the first you'll find.
@michaelsteinberg9727
@michaelsteinberg9727 6 лет назад
haha, competent in c++
@Hydragurum
@Hydragurum 8 лет назад
cpp is more like a high level assembler than a high level programming language. After learning python I don't see a real reason to go back to cpp
@GingerGames
@GingerGames 8 лет назад
+Hydragurum Not really. C++ is lower level than most languages but it is still high(ish) level programming languages. To be a high level assembler, you would need each statement be easily translated into assembly code which C++ cannot do (C may have been able in the '70s/'80s though). The reason why you would want to use C++ rather than python is if you want control of the system. You want manual memory management and care about performance.
@Hydragurum
@Hydragurum 8 лет назад
Ginger Games​ In other words if you want to write malware, or have buggy code with unpredictable crashes that can take weeks or months to debug, or have much longer development times, sure use cpp. I personally haven't come across programs that require such extreme optimization, and if they do they're probably written in assembly. Studies do show that code written in cpp performs only marginally better than modern interpreted languages. But if all you consider is marginal returns on runtime performance as opposed to the overall issues with software quality and development time, then I see the appeal of cpp. I am just an amateur wannabe programmer though so I could be wrong. I do love all the cool shit you guys do and talk about though! Keep it coming
@GingerGames
@GingerGames 8 лет назад
You are clearly talking out of your arse, so I am not going to discuss this further.
@Hydragurum
@Hydragurum 8 лет назад
Ginger Games But I'm not. Sure I'm not talking from my own experience, but from the experience of others. What directed me to look up this video was an article about why c and cpp are bad from a professional programmer on Radford.edu. And a lot of what I said stems from that reading.
@Hydragurum
@Hydragurum 8 лет назад
+Ginger Games I edited my last comment you replied to. I didn't anticipate you would reply so fast. I qualified everything I said by saying I am an amateur wannabe and could be wrong. But I really am only parroting other professional programmers. What I can say from experience though is I did study some bioinformatics in college and Perl was the language of choice for even computationally intensive programs... not cpp. That struck me because I always believed in college that you should use cpp to make programs more powerful, notwithstanding my fondness for Python. So all I am doing is echoing sentiments of others. Please understand that I in no way underestimate or impugn your expertise, and I appreciate any correction and feedback
@ajflink
@ajflink 5 лет назад
Programming classes use outdated methodology in C++ and the language is not dynamic or flexible without hundreds and thousands of lines of code to do something simplistic. There is memory leaks, those annoying and somewhat illogical pointers, and errors are hard to handle post-coding.
@MichaelLehnGermany
@MichaelLehnGermany 4 года назад
C++ never had garbage collection ...
@GingerGames
@GingerGames 4 года назад
I never said it did.
@zeratulzum9719
@zeratulzum9719 8 лет назад
Guy, just say you don't like it and stop the bullshit.
@monomii2841
@monomii2841 8 лет назад
excuse me, do you know what a rant is?
Далее
I made the same game in Assembly, C and C++
4:20
Просмотров 777 тыс.
Когда Долго В Рейсе)))
00:16
Просмотров 147 тыс.
СОБАКА И  ТРИ ТАБАЛАПКИ Ч.2 #shorts
00:33
Deep thoughts on other languages Like Rust, Go, etc.
5:57
Bjarne Stroustrup: C++ | Lex Fridman Podcast #48
1:47:13
zig will change programming forever
9:34
Просмотров 337 тыс.
Advice for Writing Small Programs in C
1:45:24
Просмотров 149 тыс.
Casey Muratori on Recognizing Your Passion
6:23
Просмотров 17 тыс.
Why C++ Scares the Crap Out of Me
4:21
Просмотров 4,3 тыс.
31 nooby C++ habits you need to ditch
16:18
Просмотров 810 тыс.
Когда Долго В Рейсе)))
00:16
Просмотров 147 тыс.