Live data from Hacker News

Comparison of C/POSIX standard library implementations for Linux

etalabs.net

31–40 of 58 posts

Re: Comparison of C/POSIX standard library implementations for Linux

#31

Earlier quoted context omitted.

What's Fil-C? Okay, found it myself, looks cool: https://github.com/pizlonator/llvm-project-deluge/ What's yoyoland? All I can find is an amusement park in Bangkok, and some 1990s-era communication software for Classic Mac OS: https://www.macintoshrepository.org/39495-yoyo-2-1

The Fil-C stack is composed of : - Userland: the place where you C code lives. Like the normal userland you're familiar with, but everything is compiled with Fil-C, so it's memory safe. - Yololand: the place where Fil-C's runtime lives. Fil-C's runtime is about 100,000 lines of C code (almost entirely written by me), which currently has libc as a dependency (because the runtime makes syscalls using the normal C funct…

Why does yoyoland need to use libc’s memcpy? Can’t you just use __builtin_memcpy?

On Linux, if all you need is syscalls, you can just write your own syscall wrapper-like Go does.

Doesn’t work on some other operating systems (e.g. Solaris/Illumos, OpenBSD, macOS, Windows) where the system call interface is private to the system shared libraries

Re: Comparison of C/POSIX standard library implementations for Linux

#32

Earlier quoted context omitted.

The Fil-C stack is composed of : - Userland: the place where you C code lives. Like the normal userland you're familiar with, but everything is compiled with Fil-C, so it's memory safe. - Yololand: the place where Fil-C's runtime lives. Fil-C's runtime is about 100,000 lines of C code (almost entirely written by me), which currently has libc as a dependency (because the runtime makes syscalls using the normal C funct…

Why does yoyoland need to use libc’s memcpy? Can’t you just use __builtin_memcpy? On Linux, if all you need is syscalls, you can just write your own syscall wrapper-like Go does. Doesn’t work on some other operating systems (e.g. Solaris/Illumos, OpenBSD, macOS, Windows) where the system call interface is private to the system shared libraries

> Why does yoyoland need to use libc’s memcpy? Can’t you just use __builtin_memcpy?

Unless you do special things, the compiler turns __builtin_memcpy into a call to memcpy. :-)

There is __builtin_memcpy_inline, but then you're at the compiler's whims. I don't think I want that.

A faithful implementation of what you're proposing would have the Fil-C runtime provide a memcpy function so that whenever the compiler wants to call memcpy, it will call that function.

> On Linux, if all you need is syscalls, you can just write your own syscall wrapper-like Go does.

I could do that. I just don't, right now.

You're totally right that I could remove the yolo libc. This is one of like 1,000 reasons why Fil-C is slower than it needs to be right now. It's a young project so it has lots of this kind of "expedient engineering".

Re: Comparison of C/POSIX standard library implementations for Linux

#33

Earlier quoted context omitted.

That’s mostly true, but not quite. For instance, suppose you aim to support all of 32/64-bit and little/big-endian. You’ll likely end up factoring straightforward math operations out into standalone functions. Granted, those will probably get inlined, but it may mean your structure is more abstracted than it would be otherwise. Just supporting the options has implications. That’s not the strongest example. I just mea…

The way glibc's source works (for something like math functions) is that essentially every function is implemented in its own file, and various config knobs can provide extra directories to compile and provide function definitions. This can make actually finding the implementation that's going to be used difficult, since a naive search for the function name can turn up like 20 different function definitions, and work…

People don't typically implement math functions by pulling bits out of a reinterpreted floating point number. If you rely on the compiler, you get whatever it decides for you, which might be something dumb like float80.

Re: Comparison of C/POSIX standard library implementations for Linux

#35
post #22

Earlier quoted context omitted.

Note that dietlibc is the project of a sole coder in the CCC sphere from Berlin (Fefe). His main objective was to learn how low level infra is implemented and started using it in some of his other projects after realizing that there is a lot of bloat he can skip with just implementing the bare essentials. Musl has a different set of objectives.

I follow diet but it is definitely not ready for general use like musl and probably never will be. There aren't a lot of eyeballs on it.

That's what I'm saying. It's not Fefe's objective to make it fit for everybody...

Re: Comparison of C/POSIX standard library implementations for Linux

#36

Earlier quoted context omitted.

In case of glibc I think what you said is orthogonal to its bloat. Yes, it has complex implementations but since they are for a good reason I'd hardly call them bloat. Independently from that glibc implements a lot of stuff that could be considered bloat: - Extensive internationalization support - Extensive backward compatibility - Support for numerous architectures and platforms - Comprehensive implementations of op…

Ok, fair points, although internationalization seems like a reasonable thing to include at first glance. Is there a fork of glibc that strips ancient or bizarre platforms?

"Internationalization" is a very broad item that can include e.g. support for non-UTF-8 locales, which is something few Linux distros need today.

Re: Comparison of C/POSIX standard library implementations for Linux

#37
It’s amazing how much code gets pulled in for printf. Using musl, printf apparently adds 13kb of code to your binary. Given format strings are almost always static, it’s so weird to me that they still get parsed at runtime in all cases. Modern compilers even parse printf format strings anyway to check your types match.

This sort of thing makes me really appreciate zig’s comptime. Even rust uses a macro for println!().

Re: Comparison of C/POSIX standard library implementations for Linux

#39
post #37

It’s amazing how much code gets pulled in for printf. Using musl, printf apparently adds 13kb of code to your binary. Given format strings are almost always static, it’s so weird to me that they still get parsed at runtime in all cases. Modern compilers even parse printf format strings anyway to check your types match. This sort of thing makes me really appreciate zig’s comptime. Even rust uses a macro for println!()…

In larger programs, that compile time parsing can lead to even more code, as the function is essentially instantiated and compiled separately for each and every invocation. The type erasure provided by printf, can be a blessing in _some circumstances_.

That being said, in those larger programs, it's still likely going to be a negligible part of the binary size, and the additional code paths are unlikely to affect performance unless you're doing string formatting in multiple hot-paths which is generally a poor choice anyway.

Re: Comparison of C/POSIX standard library implementations for Linux

#40
post #37

It’s amazing how much code gets pulled in for printf. Using musl, printf apparently adds 13kb of code to your binary. Given format strings are almost always static, it’s so weird to me that they still get parsed at runtime in all cases. Modern compilers even parse printf format strings anyway to check your types match. This sort of thing makes me really appreciate zig’s comptime. Even rust uses a macro for println!()…

If you use any level of compiler optimisation both clang and GCC will convert calls to printf into calls to puts (which is much simpler) if they detect there's no formatting done
Post reply on HN