←back to thread

383 points hkalbasi | 4 comments | | HN request time: 0s | source
Show context
kryptiskt ◴[] No.42815776[source]
What would be refreshing would be a C/C++ compiler that did away with the intermediate step of linking and built the whole program as a unit. LTO doesn't even have to be a thing if the compiler can see the entire program in the first place. It would still have to save some build products so that incremental builds are possible, but not as object files, the compiler would need metadata to know of the origin and dependencies of all the generated code so it would be able to replace the right things.

External libs are most often linked dynamically these days, so they don't need to be built from source, so eliminating the linker doesn't pose a problem for non-open source dependencies. And if that's not enough letting the compiler also consume object files could provide for legacy use cases or edge cases where you must statically link to a binary.

replies(2): >>42816272 #>>42817207 #
dapperdrake ◴[] No.42817207[source]
SQLite3 just concatenation everything together into one compilation unit. So, more people have been using this than probably know about it.

https://sqlite.org/amalgamation.html

replies(2): >>42818061 #>>42818178 #
jdxcode ◴[] No.42818061[source]
I totally see the point of this, but still, you have to admit this is pretty funny:

> Developers sometimes experience trouble debugging the quarter-million line amalgamation source file because some debuggers are only able to handle source code line numbers less than 32,768 [...] To circumvent this limitation, the amalgamation is also available in a split form, consisting of files "sqlite3-1.c", "sqlite3-2.c", and so forth, where each file is less than 32,768 lines in length

replies(1): >>42819503 #
yellowapple ◴[] No.42819503[source]
That would imply that such debuggers are storing line numbers as not just 16-bit numbers (which is probably sensible, considering that source files longer than that are uncommon), but as signed 16-bit numbers. I can't fathom a situation where line numbers would ever be negative.
replies(4): >>42819971 #>>42820009 #>>42820102 #>>42820625 #
eredengrin ◴[] No.42820102[source]
It's not that uncommon of a convention to strictly use signed numbers unless doing bit manipulation, eg the Google C++ Style Guide.
replies(1): >>42821025 #
1. rocqua ◴[] No.42821025{3}[source]
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.

replies(1): >>42836694 #
2. yellowapple ◴[] No.42836694[source]
> 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.
replies(1): >>42837678 #
3. eredengrin ◴[] No.42837678[source]
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.
replies(1): >>42840477 #
4. yellowapple ◴[] No.42840477{3}[source]
That's what I'm saying, though: rollovers can happen regardless of whether the integer is signed or unsigned. x + 1 > x is never a safe assumption for integers of the same fixed width, no matter if they're i16 or u16. Whether it's specifically acknowledged as defined or undefined behavior doesn't really change that fundamental property of fixed-width integer addition.

(As an aside: I'm personally fond of languages that let you specify what to do if an integer arithmetic result doesn't fit. Zig, for example, has separate operators for rollover v. saturation v. panicking/UB, which is handy. Pretty sure C++ has equivalents in its standard library.)