5 ms·
I would argue that you pay a harder mental cost in C because each project has to reinvent its own convention to emulate C++ features, and also because C allow f
by varajelle 5y ago
I would argue that you pay a harder mental cost in C because each project has to reinvent its own convention to emulate C++ features, and also because C allow for less abstraction which makes reasoning about the whole program more difficult
I don't see the relation with the fact that msvc and GCC have chosen different c++ ABI. That's not telling anything about the complexity of the language.
- flohofwoe 5y agoIf you feel the need to emulate C++ features in C then you're just writing C code with a C++ mindset. Getting back to the "C way" takes a couple of months to get C++ out of your system first ;) Of course for some types of problems, C++ is indeed the better language than C, but very often other languages are even better suited (e.g. I turn to Python for most problem where C doesn't work well, for instance munching text files)
- varajelle 5y agoI was referring to the things from the video, where RAII and generic types are emulated with complex macros. And where std::string(_view) is re-invented
- flohofwoe 5y agoFair point, but cleanup and string handling are hardly problems where C++ has a monopoly, or even particularly good solutions to offer ;)
- jstimpfle 5y agoYou are probably referring to the defer() macro, which is well suited for some cases and not too unergonomic to use. I've used this for multiple years, and I still love it, together with X-macros they are some of the most important tricks I would advice any C programmer to try out. Sometimes with defer() you might get a difficult to read error message when you're doing something wrong, but it's galactically easier to deal with than the standard STL error spew that so many C++ programmers have just come to accept, and it's hard to do something wrong in the first place (just put simple expressions as arguments). A comparison of defer() with RAII is not that meaningful, as they are totally different things. RAII is this complicated system that leads to (requires) other more complicated stuff like {default,copy,move,assignment...}{constructor/destructors} as well as exceptions, with all sort of terrible interactions and implicit behaviour, that can easily get out of hand and make your code an unreadable mess and/or produce terribly inefficient (piece-meal allocations/function calls) and slow-compiling code (huge header includes). In the simple situations where defer() is a win, if you use (just) RAII instead, you always have to declare a class out-of-line first (using weird braces and all) to get ad-hoc behaviour, while with defer() macro you can just make something up on the spot, which is often a better way. I'm not saying there can't be experienced coders who use RAII well in some situations, but personally I opt to just not use it, since the price seems far to high for the benefits, outside of say primitive use in leetcode assignments.
- ogoffart 5y agoThe problem with defer is that it is a macro with all its problem. Imagine such code for (int i = 0; i < files_count; ++i) { file_handle_t handle = open_file(files[i]); defer(close_file(handle)) { // ... if (some_condition) { close_file(handle); break; } // ... } } But this doesn't work because you did not know or you forgot that `defer` was implemented with a `for` inside and so the `break` or `continue` goes out of the wrong loop. and that's just one example of the many thing that can go wrong because it is a macro. On the other hand, with RIAA, you just have your file_handle that automatically close so you can't forgot to close it, and the rules are well known and not that difficult to understand.
- jstimpfle 5y agoIt's indeed a problem that has happened to me, which is why I like to make the macro like for DEFER(init, exit) { } or at least give it a name that indicates clearly that this is syntactically a loop. That's like with some iteration macros that I like to use as well from time to time. The basic idea is to never try to hide what you're doing, since that will backfire. You can still take a balanced approach with DRY and separation of concerns principles, which can lead to reasonable macros. > and that's just one example of the many thing that can go wrong because it is a macro. I'm inclined to say that nothing can go wrong in above usage, or at the very least it would take criminal energy to break it (I really can't come up with a case right now). It's perfectly doable to write safe macros with only a little experience. Follow these simple rules when defining macros: 1) parenthesize usages of macro params, and parenthesize the whole macro body if it is a complete expression. 2) Use parameters that take syntactical expressions only once, to prevent evaluating side-effects (like x++) multiple times. Linux kernel even allows for declaration of local variables in macros by using expression statement blocks (GCC extension). Although I've never had a need for them, I believe that with this approach you can fulfill rule 2) in all possible situations. You can improve macro safety in cases where you need to define a macro that is a little dangerous by just capitalizing the macro's name to make clear at the call site to be a little bit careful here. The thing is, there is no need to be 100% safe. It's very good to be 99% safe and have a simple to use mechanism. Because there are always so many other ways to break your programming, and if you're trying to be 100% safe at the cost of being twice as hard to use, that's effectively a net loss because you're provoking problems in other ways. > On the other hand, with RIAA, you just have your file_handle that automatically close so you can't forgot to close it, and the rules are well known and not that difficult to understand. Could agree if it's a file handle or something other off-the-shelf thing where you don't have to make the class yourself, and everybody instinctively is aware of the implicit behaviour. Otherwise, I very much like the more explicit behaviour and ad-hoc convenience that a defer() macro gives me.
- formerly_proven 5y ago> If you feel the need to emulate C++ features in C then you're just writing C code with a C++ mindset. Ah, classic no true scotsman'ism. No real C programmer would emulate classes, an object system, virtual dispatch, templates, ...
- maccard 5y ago> If you feel the need to emulate C++ features in C then you're just writing C code with a C++ mindset. So you need a C++ mindset to have a use for a dynamic array, a hash table, threads or namespaces, all cross platform? (Yes windows is a platform too) That's without considering raii! (which does admittedly have some baggage wrt the functions you need to implement.)
- flohofwoe 5y agoDynamic arrays, hash tables, threads: C++ doesn't have those either as language constructs, they are only implemented in the standard library. Namespaces: prefixes work just fine in C and don't require name mangling. RAII makes no sense with C's concept of "dumb data" instead of C++'s "smart objects".
- maccard 5y agoWhether it's part of the language or the standard library is arguing semantics; Support for type safe dynamic arrays is something that C++ has that C doesn't, is widely used, and poorly reomplemented in C using macros (if you're lucky). >Namespaces: prefixes work just fine in C and don't require name mangling. This is a perfect example of a feature that solves a problem that C has (global namespace pollution). Prefixing is a bandaid, and a nasty one at that. Everyone loves #define NOMINMAX in the windows headers, and prefixing all their code with a faux namespace, dirtying _all_ of the code. > RAII makes no sense with C's concept of "dumb data" instead of C++'s "smart objects". Sure it does. Every call to fopen should be paired with a call to fclose, every malloc with a free. RAII practically eliminates a whole category of issues around resource leaks; in over a decade of writing C++ professionally, almost every instance of a memory leak, stomp or resource leak was someone trying to be "clever" and drop down to more C style code.
- ogoffart 5y agoWhy do namespaces require name mangling? One could imagine just using :: in the symbol name. Anyway, even C has name mangling: For example, on Windows, all C symbols gets prefixed by an underscore https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/name-decoration?redirectedfrom=MSDN&view=msvc-160 https://docs.microsoft.com/en-us/cpp/error-messages/tool-err... And even on macOS there is something about having symbols starting with \1