Live data from Hacker News

Wild – A fast linker for Linux

github.com

201–210 of 222 posts

Re: Wild – A fast linker for Linux

#201

Earlier quoted context omitted.

I mean, sorry for the snark but really, there's so many of these things that it's just ridiculous to even attempt to compare. e.g. I wouln't ever use something like string_view or span unless the code is absolutely performance critical. There's a lot of defensive copying in C(++), because all the risks of losing track of pointers are just not worth it. In Rust, you can go really wild with this, there's no comparison.

> because all the risks of losing track of pointers are just not worth it. These risks are mostly, and often entirely, gone when you write modern C++. You don't lose track of them, because you don't track them, and you only use them when you don't need to track them. (Except for inside the implementations of a few data structures, which one can think of as the equivalent of unsafe code in Rust). Of course I'm general…

I don't see how modern C++ solves any of those problems, and especially without performance implications.

Like, how do you make sure that you don't hold any dangling references to a vector that reallocated? How do you make sure that code that needs synchronization is synchronized? How do you make sure that non-thread safe code is never used from multiple threads? How do you make sure that you don't ever invalidate an iterator? How do you make sure that you don't hold a reference to a data owned by unique pointer that went out of scope? How do you make sure you don't hold a string view for a string that went out of scope?

As far as I know (and how I experienced it), the answer to all of those questions is to either use some special api that you have to know about, or do something non-optimal, like creating a defensive copy, use a shared pointer or adding "just in case" mutex, or "just remember you might cause problem a and be careful."

In Rust all of those problems are a compile error and you have to make an extra effort to trigger them at runtime with unsafe code. That's a very big difference and I don't understand how can modern C++ come even close to it.

Re: Wild – A fast linker for Linux

#202
post #200
post #191

Earlier quoted context omitted.

The __LINE__ macro, like all other macros, is expanded during the preprocessing of the source code and is not handed to the debugger in any way.

Yes... And debuggers that implement line numbers, generally work by taking that information as part of the preprocessing stage. And the #line and __LINE__ macro/directive were implemented _for debuggers_ when originally created. They were made to be handed over to the debugger. If you simply compile and run, the debugger won't have __LINE__, no. But it also won't have line numbers, at all. So you might have missed a…

No, the debugger does not get involved in preprocessing. When you write "a = __LINE__;", it expands to "a = 10;" (or whatever number) and is compiled, and the debugger has no knowledge of it. Debugging information, including the mapping of positions in the code to positions in the source, is generated by the compiler and embedded directly into the generated binary or an external file, from which the debugger reads it.

The __LINE__ macro is passed to the debugger only if the program itself outputs its value, and the "debugger" is a human reading that output :)

Re: Wild – A fast linker for Linux

#203

Earlier quoted context omitted.

> because all the risks of losing track of pointers are just not worth it. These risks are mostly, and often entirely, gone when you write modern C++. You don't lose track of them, because you don't track them, and you only use them when you don't need to track them. (Except for inside the implementations of a few data structures, which one can think of as the equivalent of unsafe code in Rust). Of course I'm general…

I don't see how modern C++ solves any of those problems, and especially without performance implications. Like, how do you make sure that you don't hold any dangling references to a vector that reallocated? How do you make sure that code that needs synchronization is synchronized? How do you make sure that non-thread safe code is never used from multiple threads? How do you make sure that you don't ever invalidate an…

> Like, how do you make sure that you don't hold any dangling references to a vector that reallocated?

So, I'll first nitpick and say that's not a problem with pointer tracking.

To answer the question, though:

When I'm writing a function which receives a reference to a vector, then - either it's a const reference, in which case I don't change it, or it's a non-const reference, in which case I can safely assume I'm allowed to change it - but I can't keep any references or pointers into it, or iterators from it etc. I also expect and rely on functions that I call with a non-const reference to that vector, to act the same.

And when I create a vector, I just rely on the above in functions I call.

This is not some gamble. It's how C++ code is written. Yes, you can write code which breaks that principle if you like, but - I don't, and library authors don't.

> How do you make sure that code that needs synchronization is synchronized?

You mean, synchronization between threads which work on the same data? There's no one answer for that. It depends. If you want to be super-safe, you don't let your threads know about another other than multithread-aware data structures, whose methods ensure synchronization. Like a concurrent queue or map or something. If it's something more performance-critical whether synchronization is too expensive, then you might work out when/where it's safe for the threads to work on the same data, and keep the synchronization to a minimum. Which is kind of like unsafe Rust, I imagine. But it's true that it's pretty easy to ignore synchronization and just "let it rip", and C++ will not warn you about doing that. Still, you won't enter that danger zone unless you've explicitly decided to do multithreaded work.

About the Rust side of things... isn't it Turing-complete to know whether, and when, threads need to synchronize? I'm guessing that safe Rust demands that you not share data which has unsynchronized access, between threads.

> the answer to all of those questions is to either use some special api that you have to know about

C++ language features and standard library facilities are a "special API" that you have to know about. But then, so are raw pointers. A novice C++ programming student might not even be taught about using them until late in their first programming course.

My main point was, that if you talk about "C/C++ progamming", then you will necessarily not use most of those language features and facilities - which are commonly used in modern code and can keep you safe. You would be writing C-like code, and will have to be very careful (or reinvent the wheel, creating such mechanisms yourself).

Re: Wild – A fast linker for Linux

#204
post #170

Earlier quoted context omitted.

It's not that uncommon of a convention to strictly use signed numbers unless doing bit manipulation, eg the Google C++ Style Guide.

Notably, unsigned integers also have defined behavior for overflow. This means compilers can do less optimization on unsigned integers. For example, they can't assume that. x + 1 > x for unsigned ints, but are free to assume that for standard ints. That is just another reason to stick with signed ints unless there is a very specific behavior you rely on.

> For example, they can't assume that. x + 1 > x for unsigned ints, but are free to assume that for standard ints.

No they ain't:

    julia> x = typemax(Int16)
    32767
    
    julia> x + Int16(1) > x
    false
Integers are integers, and can roll over regardless of whether or not they're signed. Avoiding rollover is not a reason to stick with signed integers; indeed, rollover is a very good reason to avoid using signed integers unless you're specifically prepared to handle unexpectedly-negative values.

Re: Wild – A fast linker for Linux

#205

Earlier quoted context omitted.

I think you should get new lawyers if this is their understanding of how software licenses work.

I'm wondering if you've ever actually asked a real corporate lawyer for an opinion on anything relating to GPL licenses. The results are pretty consistent. I've made the trip on three occasions, and the response each time was: "this was not drafted by a lawyer, it's virtually ininterpretable, and it is wildly unpredictable what the consequences of using this software are."

Why do some companies engage with it then?

Re: Wild – A fast linker for Linux

#206
post #170

Earlier quoted context omitted.

Notably, unsigned integers also have defined behavior for overflow. This means compilers can do less optimization on unsigned integers. For example, they can't assume that. x + 1 > x for unsigned ints, but are free to assume that for standard ints. That is just another reason to stick with signed ints unless there is a very specific behavior you rely on.

> For example, they can't assume that. x + 1 > x for unsigned ints, but are free to assume that for standard ints. No they ain't: julia> x = typemax(Int16) 32767 julia> x + Int16(1) > x false Integers are integers, and can roll over regardless of whether or not they're signed. Avoiding rollover is not a reason to stick with signed integers; indeed, rollover is a very good reason to avoid using signed integers unless…

It depends on the language. I linked a set of c++ guidelines and for c++, they are correct: it is undefined behaviour to do signed integer overflow. Some languages do specify it, eg rust, and even in c++ it might appear to work, but even then it is still undefined and should be strongly avoided.

Re: Wild – A fast linker for Linux

#207

Earlier quoted context omitted.

They don't have to release source for internal forks.

They do if they're AGPL licensed and the internal form software is used to provide a user facing service.

But then it isn’t “internal”…

Re: Wild – A fast linker for Linux

#208

Earlier quoted context omitted.

I think you should get new lawyers if this is their understanding of how software licenses work.

I'm wondering if you've ever actually asked a real corporate lawyer for an opinion on anything relating to GPL licenses. The results are pretty consistent. I've made the trip on three occasions, and the response each time was: "this was not drafted by a lawyer, it's virtually ininterpretable, and it is wildly unpredictable what the consequences of using this software are."

Eh, all the GNU family of licenses were drafted by lawyers.

Just using any Copyleft software has no legal consequences (copyleft licenses kick in when distributing, not using them).

Re: Wild – A fast linker for Linux

#209
post #133

Earlier quoted context omitted.

Why does AGPL Vs MIT matter for a linker?

Hmm, my naive summary of AGPL is "If you run AGPL code in your web backend you are obliged to offer the backend source to everyone using a web client". No wonder it's explicitly forbidden at Google. What does that mean for a linker? If you ship a binary linked with an AGPL linker you need to offer the source of the linker? Or of the program being linked?

Instead of spreading FUD you could go read the AGPL.

Re: Wild – A fast linker for Linux

#210

Ever since mold relicensed from AGPL to MIT (as part of mold 2.0 release), the worldwide need for making another fast linker has been greatly reduced, so I wasn't expecting a project like this to appear. And definitely wasn't expecting it to already be 2x faster than mold in some cases. Will keep an eye on this project to see how it evolves, best of luck to the author.

Maybe I'm holding it wrong, but mold isn't faster at all if you're using LTO, which you probably should be.

You should be using LTO where incremental build times are a concern, i.e. for development builds.

And for realease builds link time is hardly a concern.

Post reply on HN