4

I'm working on a kernel. One of the tasks in writing a kernel is that a C library must be ported. Some functions such as memcmp, strlen and so on have to be rewritten. Most of the time I see the code written in C, and then wrapped in extern "C". However, this complicates my build process because there's a lot of files written in C, and a lot of files written in C++, that must be linked together and it's just a headache. IT would be nice if the entire thing could be written in C++.

Would this make sense?

user142809
  • 41
  • 1
  • 6
    From the C++ standard point of view you can implement the standard library in COBOL as long as it does what the standard says it should. – Baum mit Augen Oct 15 '15 at 03:32
  • 1
    Mixing `C++` with `C` libraries should not be a problem. Can you clarify your issue? – Galik Oct 15 '15 at 03:35
  • 3
    I'm not exactly sure what the stdlib/libc has to do with a kernel, but if you want to C (or assembly) code to link with your library, the functions need to be compiled with `extern "C"` so you don't have the C++ name mangling issues. – Russ Schultz Oct 15 '15 at 03:36
  • @Galik Mixing a pre-written library like Newlib isn't a problem. But that's more for userspace. For the actual kernel, I can't use an existing C library. – user142809 Oct 15 '15 at 03:37
  • 6
    "One of the tasks in writing a kernel is that a C library must be ported." - nope, you can write a kernel without a C library if you want to, or with something totally different. It's up to you. – user253751 Oct 15 '15 at 04:10
  • 2
    Do you want to use it from within kernel code, or provide it to user applications? Either way, as long as in the end you have an object file with the needed symbols, correct calling convention and the standardised behaviour behind each of them you can write that C library in probably almost any language you like. `extern "C" ` is only needed to stop the C++ compiler from trying to search for the mangled names, and as such it's only needed around the declarations of the functions. – Daniel Jour Oct 15 '15 at 05:00
  • 1
    Why do you think `memcmp()` and friends have to be rewritten? There are ways to write these in standard C that don't require any porting at all. – user207421 Oct 15 '15 at 05:05
  • "One of the tasks in writing a kernel is that a C library must be ported." - you could use existing library. [Gnu C Library](https://en.wikipedia.org/wiki/GNU_C_Library#Supported_hardware_and_kernels), for example, does run on variety of kernels. – el.pescado - нет войне Oct 15 '15 at 06:35
  • I am really confused. You're at the skill level of writing a kernel and your big problem is using a mix of 2 languages in your make file? Surely tidying up the makefile you should be able to make something that's not too ugly. Also do you really want to abandon C code for C++ in the kernel? If you're just writing C in a CPP file and wrapping it in extern C no that doesn't make much sense to me. And if you're using CPP code wouldn't there be a cost in efficiency? – Sammy Oct 15 '15 at 06:50
  • @Sammy No. C++ can be way more efficient than C, even at low levels (you can search for embedded C/C++ and see for yourself). Plus C++ gives you RAII for free. (in C, RAII is only available if you write one function per object you create, a killer). – Alexis Wilke Jul 17 '21 at 16:22
  • "this complicates my build process" Show, don't tell. Where are the complications? Show your build script, point out the exact places you don't like. – n. m. could be an AI Jul 17 '21 at 18:19
  • @AlexisWilke: When kernel is allocating resources on behalf of user-space RAII makes about as much sense as waking up a question that has laid dormant for over 5 years and then trying to make off-topic comments to someone that hasn't logged in since 2017. – Brendan Jul 17 '21 at 19:52
  • @Brendan Apparently it can be useful to others, since you've seen the message and I think that's what stackoverflow is about. Not 100% based on the OP or the very person who made a comment. – Alexis Wilke Jul 17 '21 at 20:05

1 Answers1

1

If that port is only for your kernel, then you can very well do whatever you want. If you plan on offering access to that library to your kernel users, then the interface has to be C. The implementation, however, can be any language you want.

Now for most functions, it doesn't make much sense to use a C++ function and then create a C function to access the C++ function since the function itself is not going to use C++ (at least for functions such as strlen(), you wouldn't really need to use the std::find(), you can rewrite that in C with a simple loop).

You could also reuse the functions you need from the GNU C library. i.e. just copy those functions to your implementation. Just make sure to keep the same license. That library has many implementations of such low level functions in various assembly languages for speed. The strlen() function, for example, loads 64 bits and determines whether there is a 0x00 byte using logic (NOT, AND, XOR...) which makes the function extremely efficient.

The GNU C library also includes special functions that call kernel functions. Those, obviously, you wouldn't want directly in your kernel (well, probably not, it will depend on your kernel).

Finally, the C library is much more complex than just a few functions like strlen(). It has to work with thousands of software, all of which may be linked against slightly different versions. So the strlen() may actually have 20 versions within the same C library. Probably not something you'd want to worry about for a while (until your kernel gets used by many), but it can be important for long term stability of the software running on your computer. This is particularly important if one software expects a certain function to return EINVAL (older version) and another that returns EIO (newer version). Such tiny difference are really important when dealing with thousands of software.

Yet again, it sounds like what you means is having helper functions in your kernel. Helper functions which are available in the C library but are not an actual C library (I don't think it's a good idea for the kernel to be linked in this way). It should be your helper function library specific to your kernel, which you link statically. Actually, you should only add functions that are used by your kernel, no more than that.

Finally, if your kernel is written in C++, then your helper functions can as well be written in C++. However, if you plan to have some small parts that use just C and some of these helper functions would be used in those small parts, then having those helper functions written in C is going to be easier. strlen() is obviously only necessary in C since in C++ you'd like to use the std::string::length() member of function instead.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • One note: `You could also reuse the functions you need from the GNU C library. i.e. just copy those functions to your implementation` and then follow the GNU General Public License the GNU C library is licensed with, which for a kernel basically means it has to be open source. – KamilCuk Jul 17 '21 at 16:48
  • @KamilCuk Yeah, pretty much. OP didn't specify whether it would need to be one way or the other. – Alexis Wilke Jul 17 '21 at 16:50