Rewriting old code from 2 years ago, but this time it will actually be good! I've been semi-regularly rewriting the data structure library I use for my C projects for 6 years now. C is my favorite programming language, but there are a lot of features I would like it to have like symbols, tuples, sets, hashtables, unification algorithms, etc. Honestly C + more data structures + automated reasoning sounds like the best.

Β· Β· 1 Β· 1 Β· 2

@wistahe Hi Wistahe! I agree, though there's something I seriously miss in C, and that's exception handling. If C had an except/catch statement, it would be truly perfect. Missing libraries of complex data structures can be easily added...

@Eidon @wistahe Considering that C++ has all that and you can use C++ in a very C-like way, what is the reason you don't do that?

@wim_v12e @Eidon I'm not opposed to using C++, especially when there isn't a C library, but for what I'm working on I like having a lot of control over my program's runtime. Most of the time I use C in order to experiment with different execution models for representing programs in new ways, otherwise I'm writing things in Python. There's also some smaller things like compile time, error message verbosity, conceptual simplicity, name mangling, etc. Also I know just about all of C and I don't have the time anymore to learn another language (I do know a bit of C++, but I haven't used it in a few years) and I doubt I could learn all there is to C++ either (I'm a physicist, if I'm using something where I don't know how it works, it bothers me). But there are times when I would like some C++ features like inheritance in function argument types instead of either using the glib macro typecast style or just accepting void pointers to a function. Overall though, my perfect programming language is something that doesn't exist yet (arguably it isn't even a programming language, not being for programming and more the maintenance of a language that very well could be lost), and C seems like the best material to build it out of because it's just so plain simple and capable.

@wistahe @Eidon Thanks for the long answer. It is in the end purely what suits you best of course.

Just for my understanding, let's assume you wrote some C code and compile it with a C++ compiler. What is the runtime behaviour that you have less control over than in C?

@wim_v12e @Eidon That would work fine too, although a bit over kill, you can certainly still write code in C++ you have a lot of control over, especially if you write it in a C like way. There are some small things related to linking like name mangling, but that can easily be worked around. The issue is a bit more cultural and mental than a matter of capability. You can do just about everything in C in C++ and more. But C++ is large, so much so that nobody really understands all of it, so to make a project that can be understood you have to choose a section of the language and stick with it. The problem is that the choice of section becomes something more to think about and it will often turn out there was a better way of doing things as you become a better C++ programmer so that old code loses its charm. Instead of solving a problem a lot more time might be spent on choosing the right language features and libraries to use. With C, just about everyone who knows C knows C and the practices one uses while writing it are well understood. The language no longer becomes something that matters, it is just a means of implementing something more interesting in your head. You already know how the code will look because it always looks the same. When it comes to C++, I imagine you can get something like that if you are part of a team on a project which has been worked on for a long time and which has clear standards of how to write code in a certain style. As a result, development would be really fast for that project due to using both the right set of C++'s capabilities and having that set be understood. That's probably why so many games and compiler collections are written in C++. But programing language interpreters tend to be written in C because they are often written initially by a single developer, avoid C++'s runtime to begin with, and need to be easily understood by new people to be ported to new platforms.

@wistahe @EidonI see what you mean. If you use C, you don't have to restrict it artificially to keep it from getting too complicated. As C++ is indeed a very big language, restricting it to "C with some nice extras" would require very specific coding guidelines and probably special pre-commit hooks to enforce them.

@wim_v12e Yeah! Sometimes the best thing to do is keep things simple. That way you can focus on other things.

@wim_v12e @wistahe
Hi wim! It's the hidden complexity that I don't like. C is closer to my ability to capture what is going on; C++ does so many things behind the corner that I'm a little afraid of side effects...

@Eidon @wim_v12e @wistahe C is the reason people came up with the expression "nasal demons"

@amaral @Eidon @wistahe I'd never heard that phrase but C is indeed notorious for undefined behaviours.

@wim_v12e @amaral @wistahe
In my limited experience, I have feared C's undefined behaviors though I have feared even more C++ cryptically defined behaviors.

@Eidon @amaral @wistahe

People will start thinking I'm a C++ zealot if I go on like this, although the truth is I have little love for the language.

I am simply puzzled about the C/C++ divide because in practice C is a subset of C++.
So it would seem to me that one can cherry-pick C++ features one likes and just stick to C for all the rest, and in that way have the best of both worlds. But that is not what I observe in reality, and this thread illustrates that.

@wim_v12e @amaral @wistahe

Well, you literally teach me that compilers are very important players; a C compiler can be simple (sometimes, too simple); a C++ compiler is very complex (sometimes too complex, possibly?); if I compile C with C++ I feel like some of that complexity might infiltrate in my executable. Though this is most likely just an irrational fear, I'm ready to admit myself...

@Eidon @amaral @wistahe
The parser and front-end generator for C++ is definitely more complex than for C. And the template processing is quite a nightmare.

But when it comes to the optimisations for performance, they are performed on a common IR representation. So the most of the complexity of C++ is gone at that level.

The main difference between the C and C++ executables, and one of the key reasons C++ executables are larger, is run-time type information (rtti), but that is optional.

@Eidon @amaral @wistahe The above is for clang+llvm, I'm not sure if gcc has such a clean separation.

@Eidon @amaral @wistahe Anyway, my position is that modern architectures, esp. heterogeneous ones, are so complex that it is impossible for a human programmer to get optimal performance. And therefore the compiler must deliver that performance.

For example, suppose you write some great C code and it needs to run on an FPGA. Unless that is your special domain of expertise, optimising your code for that platform will be virtually impossible. The same is true, to a lesser extent, for GPUs.

@Eidon @amaral @wistahe So in those cases you have no option but to trust the compiler. But why should it be different for a modern manycore CPU target? Those platforms have been around for longer so the compilers will be better than those for GPU and FPGA.

@Eidon @amaral @wistahe This is not a language-specific argument, so I realise I have digressed from the C vs C++ conversation.

@Eidon @amaral @wistahe Looking back along the thread, I apologise for messing it up by replying to different nodes, and also for geeking out.

@wim_v12e @Eidon @wistahe Wim, I guess neither one of us will hold anything against you for geeking out.

@amaral @Eidon I know, but the thread is public, in retrospect I should have used my cybre alt.

@amaral @wim_v12e @wistahe


Changing topic -- are you going to do anything special tonight? Nothing particular here, although we're going to eat some typical Italian dishes πŸ˜ƒ

Happy New Year to the Both of You!

@Eidon @wim_v12e orecchiete a la cime di rapa?

I'll cook something simple and I'll watch a movie.

@amaral @Eidon We're not going anywhere. We never used to anyway, this is normal.
I have some champagne and I am going to cook my own orzo recipe. Then either watch a movie or continue reading in Xia Jia's collection of stories.

I am going to post a few "looking back on the past year" things too.

Happy New Year to both of you, when it comes!

@amaral @wim_v12e
No, not this time! The tradition in the south of Italy is to have lentils and pork sausages, which we interpreted as lentils and vegan sausages πŸ˜ƒ Also we'll have fried panzerotti and panettone and pumante etc etc

Then, it'll be the gambling den time! (am joking of course: Tombola and games with the Neapolitan pack of cards)

Show newer

@Eidon @amaral @wistahe If you have to debug other people's code then I can see how that would be the case.

@Eidon @wistahe

To my mind, that entirely depends on how you program in it. I personally think it is easier to write side-effect free code in C++ than in C, but ymmv.

As for doing things behind the corner, that is debatable: although C seems close to the machine, that has stopped being true long ago. This article explains it much better than I ever could:

@Eidon One of the things I rethink a lot is error handling in C. There are a number of different approaches like passing in a data structure to record errors, returning an error code, using setjmp to implement exceptions, having data types that can represent both errors and desired values, etc. But honestly, I don't like any of those approaches. The code they produce feels much more complex than it needs to be. I think the people designing Unix and the C standard understood this which is why when something goes wrong you just need to check the returned value is okay (which could be any appropriate type) then get an error code from errno. This produces really simple and clean programs, but there's a catch, you need something like errno and the standard does not provide that. errno has to be thread specific (and error reporting in general needs to be thread specific because different threads may make different errors at the same time) and there usually isn't a good way to get thread specific variables automatically and without the risk of errors in the process. Luckily C now has thread_local which solves that problem and I feel will quickly become my preferred method of handling errors (aside from parsing which should be able to provide a useful message including at the very least line number). I mean, thread local variables, you don't hear about them much, but they are so useful to know about! Exception handling I like a lot in higher level languages, but for C I kind of do the exception handling manually by cleaning up what the function I'm writing introduces and then just returning with enough information so the calling function can do the same. That way it becomes clear exactly all the ways the code can fail and where it fails, and the code still remains clear! Although I can think of a really interesting use for exceptions, since they can be caught at run time and have their location tracked down, an object system might swap out one implementation of something with another and keep the program still running. I feel like exception handling has a lot of potential, but would require programs to be a lot smarter than they currently are. But that might be an interesting idea, I could see that working well with more advanced reasoning capabilities.

Sign in to participate in the conversation

We create internet services for you and your friends