4 ms·
> We now know that LP64 was the preferred choice and that it became the default programming model for 64-bit operating systems That is incorrect, Windows never
by armada651 2y ago
> We now know that LP64 was the preferred choice and that it became the default programming model for 64-bit operating systems
That is incorrect, Windows never adopted the LP64 model. Only pointers were increased to 64-bit whereas long remained 32-bit. The long datatype should be avoided in cross-platform code.
- af78 2y agoThe article focuses on Linux and FreeBSD, which are LP64.
- jagrsw 2y agoAll C's native datatypes should be avoided for cross-platform data structures (networking, databases, file storage) because the standard only guarantees minimum sizes. Additional problem is the endianess. uint64_t is a bit verbose, many re-def this to u64.
- coldpie 2y agoI think I agree, but I'd be interested in more discussion about this. I always understood the native types to be the "probably most efficient" choice, for when you don't actually care about the width. For example, you'd choose int for a loop index variable which is unlikely to hit width constraints because it's the "probably most efficient" choice. If you're forced to choose a width, you might choose a width that is less efficient for the architecture. Is that understanding correct? Historically or currently? Either way, I think I now agree that unspecified widths are an anti-feature. There's value in having explicitly specified limits on loop index variables. When you write "for(int32_t i; ...)", it causes you to think a bit, "hey can this overflow?" And now your overflow analysis will be true for all arches, because you thought about the width that is actually in use (32-bits, in this case). It keeps program behavior consistent & easier to reason over, for all arches. That's my thinking, but I'd be interested to hear other perspectives.
- 2ndbigbang 2y agoThere is int_fast32_t and int_least32_t but it is probably less confusing to just use exact sized types (and would make porting to other architectures simpler).
- kibwen 2y ago> I always understood the native types to be the "probably most efficient" choice, for when you don't actually care about the width. This itself is a platform-specific property, and is thus non-portable (not in the sense that your code won't run, but in the sense that it might be worse for performance than just using a known small integer when you can).
- nyrikki 2y agoHistorically that is incorrect. Remember that the C standard came about many years after the language was already in use, the C abstract machine wasn't an explicitly design for portability and performance, it was documenting an existing system. C compilers being performant and portable is partly due to luck but mostly due to hard work by very smart people. Last time I looked, clangs analysis and optimizing code was more than a quarter of a million lines as an example. C being imperative is probably a lens for understanding how the type of optimization you are talking about are opportunistic and not intrinsic. Another lens is to consider that the PDP11 had flat memory, but NUMA, l2 and l3 caches and deep pipelines make the compiler far more complicated despite maintaining that simple model on the abstract machine. Ironically, FORTRAN, which was written on IBM machines that had decrementing index registers. While the base one indexing is explained as being simply a choice of lowest value. In the historic context is is better conceptualized as a limit index. That more closely matches what you are describing above. If you look at the most recent CPP versions adding ranges, that is closer to both FORTRAN and the above IMHO. https://en.cppreference.com/w/cpp/ranges https://en.cppreference.com/w/cpp/ranges That history is complicated because Dennis Ritchie's work on college was on what he called 'loop programming', what we would call the structured paradigm today. That does have the concept that any loop that you know the number of iterations will always halt, but being imperative, C doesn't really enforce that although any individual compiler may. C compilers are u reasonably effective in optimization, but that is in spite of the limits of the C abstract machine, not because of it . As shown above, all it takes is one powerful actor like MS making a decision, that probably was justified at the time, to introduce side effects across all platforms. Often it is safe to assume that the compiler will make good decisions, other times you have to force it to make the correct decision. But using the default types is a decision more of a choice to value portability than about performance IMHO.
- EasyMark 2y agoI so much wish stdint would have gone with the more sane u64 i64, u32, i32, etc I redefine them for my personal projects but stick to the standard on other projects.
- kevin_thibedeau 2y agoLong shouldn't be avoided. The rule has always been 32-bits minimum. If that covers the range you need them you're good on every standards compliant platform, otherwise you use a different type. That is how the C native integer types are supposed to be used to maintain forward portability across different word size architectures. What is wrong is to blindly assume your types are larger than the minimum or exactly equal to the minimum.
- BobbyTables2 2y ago64bit systems have been around for about 20 years. In another 20 years when we have 128bit PCs, it will be comforting to know that we’ll still be hamstrung on 32bit integers because of a design choice made in the 1990s.