Any Good Websites For Learning *Just Enough* C to Understand FFI?

I know this is a Rust forum, but does anybody know of any good C websites that give enough context for C that I can understand more of what I need to learning C in the context of Rust FFI?

I don't need to really learn a lot of C, but it could be useful to have a website that explained enough of it to understand C FFI a little bit more so I can use it in the most minimal fassion necessary for binding other languages to Rust ( or just Rust to Rust over dynamic linking ). I've seen cplusplus.com, but that's C++, which probably has a lot of irrelevant stuff if I'm only intersted in C.

6 Likes

WARNING: Here be dragons!

C and C++ are notoriously badly-taught languages. The median (or maybe 99th percentile?) C and C++ programming material is full of bad advice, bad practices, archaic coding style, Undefined Behavior, or code that is just generally in bad taste.

Unfortunately, Cplusplus.com is no exception. I strongly recommend ignoring it altogether. If you need a reference-like document for either of these languages, go to cppreference.com instead (contrary to its name, it is not only C++, it also has a whole separate subsite for C).

To compound the problem, FFI is typically a topic that requires broad and detailed knowledge of C, so learning "just enough C to do FFI" approximately means "mastering C".

If you are interested in FFI, you are probably going to need to interact with the Unix C library as well. For that, you'll probably want The Open Group's POSIX man pages, an example of which you can find here. Feel free to browse around.

I have a hard time finding good C tutorials, but if you are willing to take some of the ++ (given that the basics of the two languages are very-very similar), one course I couldn't really find anything incorrect in is The Imperial College Introductory C++ Course.

An excellent resource for learning what C is not is the Comp.Lang.C Usenet FAQ. You might use it for falsifying fallacies introduced in bad C tutorials. You might even be able to follow a C tutorial and correct its mistakes using the Comp.Lang.C FAQ. While I appreciate that you will probably learn a lot in the process, pulling off this is probably outside of the level of effort required that most people are willing to sacrifice for learning C. Nevertheless, I'd wholeheartedly recommend at least skimming through it, because you'll have a much better idea of what errors to look for and what mistakes to avoid when programming in C.

12 Likes

I don't know about websites for learning C, but I have a habit of writing essays on the topic of Rust and FFI. Maybe that could point you in the right direction?

(shameless plug)

7 Likes

:+1:

OK, then I'll look be looking around to figure out what I need, try stuff out, then ask all of the super-smart people here on the forum to make sure that I'm not doing anything awful. :stuck_out_tongue: That way I don't have to become an expert overnight.

Sweet, I'll check it out.

1 Like

That's a great question, especially that FFI-specific problems are usually related to implementation details of C compilers, linkers, and operating systems, rather than the C language itself. You won't find anything useful about FFI in a "C for dummies" types of tutorials.

Unfortunately I don't know what source to recommend, because I assimilated that knowledge "the hard way" by crashing programs for my entire career :slight_smile:

Topics to look for:

  • ABI and symbol mangling. C officially doesn't have one, but in practice it's "System V ABI" most of the time (except Windows). ABI can also vary depending on CPU architecture, and especially what flavor of floating-point instructions is used.
  • Struct layout, padding, alignment issues. For pure C programs these are irrelevant implementation details, but for ABI these are essential. LP64 vs LLP64.
  • "Fragile base class problem" is C++-specific, but articles about it will explain nicely how ABI can break.
  • You need to know that Rust wants position-independent code (PIC), which C compilers need to be told to generate.
  • differences between object files, static libraries, dynamic libraries. Also the mess of linker scripts, rpath, sonames.
10 Likes

This is a big one.

For me, the most annoying part is getting the code to compile and link properly. The C story around using dependencies is pretty average, so often if I want to create a solid wrapper crate around some native library I'll end up compiling the code from source and following the compiler/linker errors to figure out what dependencies are needed.

Being able to write safe abstractions for using native code is great, but that's kinda pointless if your project doesn't compile.

2 Likes

I think I might get lucky with this and not actually need any C, because I'm realizing that for my Rust scripting solution I can probably just use extern "C" and #[repr(C)] functions and structs so that there is a stable ABI to link to, and this is just to allow Rust and C programs as scripts.

Then for other languages I can just use pre-existing Rust wrappers around the languages such as Lua, JavaScript, WASM, Python, etc. and implement the language adapters in Rust!

This might be easier than I thought. Then I keep it as Rusty as possible and avoid introducing C files into my source code directly.

1 Like

One :heart: is not enough for this excellent question, even though sadly there isn't an answer because of the pathological tradition in the C(++) community to deflect any questions about how it actually works to "it works the way your linker/system libraries/build system decides how it should work". (Although Rust is a little bit guilty of this as well with regard to LLVM.)

4 Likes

I don't think this is specific to the C/C++ community. With any sufficiently large and complex system you are going to get into situations where what you need to do is complicated and necessarily dictated by how things are done by the layers below. Quirks and all.

All non-trivial abstractions, to some degree, are leaky.

- Joel Spolsky, the Law of Leaky Abstractions

2 Likes

As someone in a very similar situation to you, how I've tried to learn C is via this book:


Which is freely available online as PDF, and these Stanford lectures:

The lectures in particular deal heavily with pointer casts, pointer arithmetic, and other wild things that C permits. I don't know if these are the best (free) resources available, but they are the best I have found.
2 Likes

That is what I thought on reading this question.

Bottom of it all is you need to have some understanding of the machine, it's instructions, how memory is used. Stack, heap, pointers, registers etc.

"Just enough C" is not going to cut it.

2 Likes