Live data from Hacker News

The Journey Before main()

amit.prasad.me

121–130 of 145 posts

Re: The Journey Before main()

#121

Earlier quoted context omitted.

> Almost freestanding. It still requires you to link against kernel32 Nitpick: the phrase “link against kernel32” feels like a Linux-ism. If you’re only calling a few function you need to load kernel32.dll and call some functions in it. But that’s a slightly different operation than linking against it. At least how I’ve always used the term link. You’re not wrong in principle. But Linux and Windows do a lot of things…

Loading means creating a memory image of the library. Linking means resolving the symbols to addresses within that memory image. Loading a library and calling some functions from it is linking. The function pointer you receive is your link to the library function.

You’re not wrong per se. But it was phrased in a very linuxy way imho.

> Linking means resolving the symbols to addresses within that memory image.

Well, you can call LoadLibrary and GetProcAddress. Which is arguably linking. But does not use the linker at link time. Although LoadLibrary is in kernel32!

Re: The Journey Before main()

#122

Earlier quoted context omitted.

> Almost freestanding. It still requires you to link against kernel32 Nitpick: the phrase “link against kernel32” feels like a Linux-ism. If you’re only calling a few function you need to load kernel32.dll and call some functions in it. But that’s a slightly different operation than linking against it. At least how I’ve always used the term link. You’re not wrong in principle. But Linux and Windows do a lot of things…

> (I think Windows does it waaay better but ymmv) Can you elaborate on that? Btw., I don't want to bash Windows here, I think the Windows core OS developers are (one of) the only good developers at Microsoft. The NT kernel is widely praised for its quality and the actual OS seems to be really solid. They just happen to also have lots of shitty company sections that release crappy software and bundle malware, ads and…

Windows 11 Pro with O&O Shutup is perfectly fine. You’re not wrong and the trend is concerning.

But on the actual topic. I think “Linux” does a few things way worse. (Technically not Linux but GCC/Clang blah blah blah).

Linux does at least three dumb things. 1) Treat static/dynamic linking the same 2) No import line 3) global system shared libraries.

All three are bad. Shared/dynamkc libraries should be black boxes. Import libs are just objectively superior to the pure hell that is linking an old version of glibc. And big ball or global shared libraries is such a catastrophic failure that Docker was invented to hack around it.

Re: The Journey Before main()

#123

Earlier quoted context omitted.

> (I think Windows does it waaay better but ymmv) Can you elaborate on that? Btw., I don't want to bash Windows here, I think the Windows core OS developers are (one of) the only good developers at Microsoft. The NT kernel is widely praised for its quality and the actual OS seems to be really solid. They just happen to also have lots of shitty company sections that release crappy software and bundle malware, ads and…

Windows 11 Pro with O&O Shutup is perfectly fine. You’re not wrong and the trend is concerning. But on the actual topic. I think “Linux” does a few things way worse. (Technically not Linux but GCC/Clang blah blah blah). Linux does at least three dumb things. 1) Treat static/dynamic linking the same 2) No import line 3) global system shared libraries. All three are bad. Shared/dynamkc libraries should be black boxes.…

Can you write that so, that people who are dumb and don't know the Windows way also get it?

Re: The Journey Before main()

#124

Earlier quoted context omitted.

> (I think Windows does it waaay better but ymmv) Can you elaborate on that? Btw., I don't want to bash Windows here, I think the Windows core OS developers are (one of) the only good developers at Microsoft. The NT kernel is widely praised for its quality and the actual OS seems to be really solid. They just happen to also have lots of shitty company sections that release crappy software and bundle malware, ads and…

Windows 11 Pro with O&O Shutup is perfectly fine. You’re not wrong and the trend is concerning. But on the actual topic. I think “Linux” does a few things way worse. (Technically not Linux but GCC/Clang blah blah blah). Linux does at least three dumb things. 1) Treat static/dynamic linking the same 2) No import line 3) global system shared libraries. All three are bad. Shared/dynamkc libraries should be black boxes.…

Linux does none of those things. That's user space stuff. Linux loads your ELF and jumps to its entry point. That's it.

Linux is so great you're actually free to remake the entire user space in your image if you want. It's the only kernel that lets you do it, all the others force you to go through C library nonsense, including Windows.

The glibc madness you described is just a convention, kept in place by inertia. You absolutely can trash glibc if you want to. I too have a vision for Linux user space and am working towards realizing it. Nothing will happen unless someone puts the work in.

Re: The Journey Before main()

#125

Earlier quoted context omitted.

MinGW is awful. Avoid. Cygwin is honestly not really something that has come up in my career. I don’t know why Linux people are so adamant to break their backs - and the backs of everyone around them - to try and do things TheLinuxWay. It’s weird. IMHo it’s far far far better and to take a “when in Rome” approach. My experience is that Linux people are MUCH worse at refusing to take a When in Rome approach than the o…

I found MinGW to be quite nice, but ymmv. > to try and do things TheLinuxWay It's not really about TheLinuxWay. It's more that Microsoft completely lacks POSIX tools at all and the compiler needs to have a complete IDE installed, which I would need a license for, and the compiler invocation also doesn't really correspond to any other compiler.

> Microsoft completely lacks POSIX tools

True!

> compiler needs to have a complete IDE installed

Not true. You can download just MSVC the toolchain sans IDE. Works great. https://stackoverflow.com/questions/76792904/how-to-install-...

> compiler invocation also doesn't really correspond to any other compiler

True. But you don’t have to use MSVC. You can just use Clang for everything.

Clang on Windows does typically use the Microsoft C++ standard library implementation. But that’s totally fine and won’t impact your invocation.

Re: The Journey Before main()

#126

Earlier quoted context omitted.

Windows 11 Pro with O&O Shutup is perfectly fine. You’re not wrong and the trend is concerning. But on the actual topic. I think “Linux” does a few things way worse. (Technically not Linux but GCC/Clang blah blah blah). Linux does at least three dumb things. 1) Treat static/dynamic linking the same 2) No import line 3) global system shared libraries. All three are bad. Shared/dynamkc libraries should be black boxes.…

Linux does none of those things. That's user space stuff. Linux loads your ELF and jumps to its entry point. That's it. Linux is so great you're actually free to remake the entire user space in your image if you want. It's the only kernel that lets you do it, all the others force you to go through C library nonsense, including Windows. The glibc madness you described is just a convention, kept in place by inertia. Yo…

Yes that’s all filed under blah blah blah.

Some people use “Linux” to exclusively refer to the Linux kernel. Most people do not.

Re: The Journey Before main()

#127
post #37

Earlier quoted context omitted.

This is one of the cornerstones that guarantee Windows can easily upgrade the C runtime and make performance and security upgrades. Win32 APIs have a different function calling ABI too. So only part of that gets "bloated" is Win32 API itself (which is spread across multiple DLLs and don't actually bloat RAM usage). Most of the time even those functions and structures are carefully designed to have some future-proofne…

I'm sick of glibc compatibility problems. Are there any recommended replacements?

For non-graphical apps, you can link statically against musl to produce a binary that only depends on the Linux kernel version and not the version or type of libc on the system. You may take a performance hit as musl isn't optimized for speed, and a size hit for shipping your own libc, and a feature hit because musl is designed to be minimal, but for many command line tools all of these downsides are acceptable.

Re: The Journey Before main()

#128

Earlier quoted context omitted.

Let's systematize this. Compilers build for target triples such as x86_64-linux-gnu. It is of the form isa-kernel-userspace. If kernel is linux, the builtin can be used. The isa determines the code generated by the compiler, both in general and for the builtin. The userspace can be anything at all, including none. Sometimes compilers build for target quadruples which also include a vendor, and that information is als…

I am not sure you understand my point. Inlining libc definitions for syscalls is fine when you only care about Debian 12 commit hash ####. It will break as soon as you think your machine is running Debian 12 and you updated it, so surely it includes the latest userspace-patches. It will also break when a user uses the OS configuration to change the behaviour of some OS functionality, but your code is oblivious to tha…

> It will break

If it ever breaks, it's a bug in the Linux kernel.

> It will also break when a user uses the OS configuration to change the behaviour of some OS functionality

Can you give concrete examples of this?

> There is syscall(2) in the libc, if you want to do this.

I know. I've written my own syscall(), as well. The idea is to put it in the compiler as a builtin so there's no need to even write it.

Re: The Journey Before main()

#129

Earlier quoted context omitted.

I'm sick of glibc compatibility problems. Are there any recommended replacements?

Glibc is half of GNU/Linux. You can of course use another libc, but it will be a different OS.

Yeah, even library loading relies on glibc, so we can't really escape glibc on GNU/Linux.

Re: The Journey Before main()

#130

Earlier quoted context omitted.

Windows 11 Pro with O&O Shutup is perfectly fine. You’re not wrong and the trend is concerning. But on the actual topic. I think “Linux” does a few things way worse. (Technically not Linux but GCC/Clang blah blah blah). Linux does at least three dumb things. 1) Treat static/dynamic linking the same 2) No import line 3) global system shared libraries. All three are bad. Shared/dynamkc libraries should be black boxes.…

Can you write that so, that people who are dumb and don't know the Windows way also get it?

> Treat static/dynamic linking the same

Imagine you have an executable with a random library that has a global variable. Now you have a shared/dynamic library that just so happens to use that library deep in its bowels. It's not in the public API, it's an implementation detail. Is the global variable shared across the exe and shared lib or not? On Linux it's shared, on Windows its not.

I think the Windows way is better. Things randomly breaking because different DLLs randomly used the same symbol under the hood is super dumb imho. Treating them as black boxes is better. IMHO. YMMV.

> No import lib (typo! lib, not line)

In Linux (not the kernal blah blah blah) when you link a shared library - like glibc - you typically link the actual shared library. So on your build machine you pass /path/to/glibc.so as an argument. Then when your program runs it dynamically loads whatever version of glibc.so is on that machine.

On Windows you don't link against foo.dll. Instead you link against a thin, small import lib called (ideally) foo.imp.lib.

This is better for a few reasons. For one, when you're building a program that intends to use a shared library you shouldn't actually require a full copy of that lib. It's strictly unnecessary by definition.

Linux (gcc/clang blah blah blah) makes it really hard to cross-compile and really hard to link against older versions of a library than is on your system. It should be trivial to link against glibc2.15 even if your system is on glibc2.40.

> global system shared libraries

The Linux Way is to install shared libraries into the global path. This way when openssl has a security vuln you only need to update one library instead of recompile all programs.

This architecture has proven - imho objectively - to be an abject and catastrophic failure. It's so bad that the world invented Docker so that a big complicated expensive slow packaging step has to be performed just to reliably run a program with all its dependencies.

Linux Dependency Hell is 100x worse than Windows DLL Hell. In Windows the Microsoft system libraries are ultra stable. And virtually nothing gets installed into the global path. Computer programs then simply include the DLLs and dependencies they need. Which is roughly what Docker does. But Docker comes with a lot of other baggage and complexity that honestly just isn't needed.

These are my opinions. They are not held by the majority of HN commenters. But I stand by all of them! Not mentioned is that Windows has significantly better profilers and debuggers than Linux. That may change in the next two years.

Also, super duper unpopular opinion, but bash sucks and any script longer than 10 lines should be written in a real language with a debugger.

Post reply on HN