Hacker News new | past | comments | ask | show | jobs | submit login

Nice! However, I'd appreciate the converse more.

I'm pretty well versed in C++, and every time I try to write something in C, I fall back to C++. I find memory management a pain without RAII, error handling a hassle without exceptions, and, well, anything really a pain without some sort of standard container library.

I have the idea that there's good alternatives for these in C-land, but I'm unfamiliar with them and would love for an expert to teach me.

In general, I wonder whether there's really that many people who know C but not C++. This might just be me projecting myself onto the world, though. Anyone?

There's no replacement for exceptions, but you can use setjmp and longjmp if you really want to jump out many layers of nested calls.

In C11 there is type generic macros that helps writing C++-like overloaded functions.

There are several extensions in GCC too.

For RAII-like memory management, there are __attribute__((constructor)) and __attribute__((destructor)).

C++ does type reflection on constant expressions via type traits templates, in GCC there is simply typeof().

If you are bored about writing static function modifiers, you can write a function inside function.

If you want to allocate a vector which won't change capacity and be released when out of local scope , for example in C++:

    auto v = std::vector<int>(n);
With C99 dynamic arrays you can use this instead:

    int v[n]; // n is a variable determined at runtime
You can use the union trick to achieve safer type casts too.

Use GObject (https://developer.gnome.org/gobject/stable/) and GLib. GObject is basically a bunch of macros to let you write OO code in C, GLib is a cross-platform set of libraries with somewhat of a 'standard library' of data structures, string handling stuff etc. It's the foundation of Gnome, it's also LGPL so that may be an issue. To be honest though I've never used it for strictly C-only code, I've only used it on Linux with gcc and it was 10 years ago.

Still, it's a nice hack for when you want to write C++-like code while still using C constructs only.

Thanks for the suggestion, I'll look into it.

That said, my first underbelly reaction is that I don't want to write C++-like code in C. Why would I do that? I might as well use C++ then. It's like writing functional code in Java. It's possible, but it's a hack.

What I'd like to learn is how to decently deal with memory, exceptional behaviour, common data structures, etc in modern idiomatic C. Some other people in this thread made some nice suggestions for that, btw, so thanks guys :)

May a thousand home-made hash tables bloom!

I kind of like the way how Zed does the error handling:


Here's my preferred way of handling errors: https://www.securecoding.cert.org/confluence/display/seccode...

I've done so little C++ so long ago that I may as well fall in the category of a C programmer who doesn't know C++. If I had spare time over the next 8 weeks I'd definitely do this as a refresher course.

>I find memory management a pain without RAII,

That statement is true. But, as you may be aware, it doesn't encompass quite a few use-cases. A lot of usecases require you to have fine control over performance and using RAII will cause random speed-bumps. for e.g. when a ref-counted smart pointer(s) goes out of scope and triggers 'heavy' destructors on held objects to free up resources - at a non-deterministic time.

The collection maybe a little eclectic, but ccan might interest you: http://ccodearchive.net

> anything really a pain without some sort of standard container library.

It's certainly not standard, but I wrote a nice little generic list library you might be interested in: http://github.com/udp/list

It uses GNU extensions, but can fallback on C++ instead if you need to build with MSVC.

I use C++ because of the std containers (vector, map, set, etc). I don't have to roll my own and I'm free to think about the problem at hand rather than how to get the proper data container for this, that and the other.

I can understand this - I know some C++ but I am not very good at it, so I usually go for C with "greenspunning", i.e. using an embedded scripting engine, e.g. guile/lua/spidermonkey

You're the first person i've heard of who falls back to C++, if that data point is of any value.

AIUI exceptions and RAII are mutually exclusive in C++. I don't know enough about C++ so i wouldn't be surprised to find out this is wrong.

> AIUI exceptions and RAII are mutually exclusive in C++

That is... very wrong. Exceptions are perilous unless you use RAII religiously (which you should; it's good.)

For more information, read up on RAII and search for "exception safety."

The definition of C++ RAII from Wikipedia: "In this language, if an exception is thrown, and proper exception handling is in place, the only code that will be executed for the current scope are the destructors of objects declared in that scope". Without this it is very hard to reap any benefits of exceptions (people have disagreements on what those are, if any, but that's another topic).

Up-voted a few of the others below too.

I also found this which I thought was a high quality summary: http://www.parashift.com/c++-faq-lite/ctors-can-throw.html

Exceptions and RAII match well, actually. Managing resources via RAII means that when an exception is thrown, the destructors of local objects are invoked so they'll release resources they've acquired.

In fact, I'd argue that you very often have to use RAII with exceptions, since there's no 'finally' block on a try-catch statement and hence it's the easiest way to ensure stuff gets cleaned up (well, except for catch(...) and rethrowing, but that's kinda ugly).

correct me if I am wrong but you can't rethrow in a destructor and hence RAII is required if you are using exceptions - because the cleanup and reporting work must be done in the destructor - unless you use global state to track failures and check after every attempted release of a resource i.e. C error checking.

> You're the first person i've heard of who falls back to C++, if that data point is of any value.

Every time I write C code is at a gun point of being forced to do so. When I have the choice between C++ and C, I always pick up C++.

I've tried several times to write new projects of mine from scratch in C just for a challenge, and have gone back to C++ every time.

Not sure what AIUI means, but the very words "exception-safe" usually imply RAII.

Applications are open for YC Winter 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact