5 ms·
I don't think there is anything wrong in writing platform-specific code; in certain circles there is this weird fetishitization of portability, placing it on th
by zokier 5y ago
I don't think there is anything wrong in writing platform-specific code; in certain circles there is this weird fetishitization of portability, placing it on the highest pedestal as a metric of quality. This happens in C programming and also for example in shell scripting, people advocating for relying only on POSIX-defined behavior. If a platform specific way of doing something works better in some use-case then there should be no shame in using that. What is important is that the code relies on well-defined behavior, and also that the platform assumptions/requirements are documented to a degree.
Of course it is wonderful that you can make programs that are indeed portable between this huge range of computers; just that not every program needs to do so.
- bombcar 5y agoC (and to some extent shell) programmers are the ones with the most experience of the machine under them changing, perhaps drastically - few other languages have even been around long enough for that to have happened. Java sidesteps this, of course, by defining a JVM to run on and leaving the underlying details to the implementation.
- Filligree 5y ago> Of course it is wonderful that you can make programs that are indeed portable between this huge range of computers; just that not every program needs to do so. Isn't most code that would behave differently on different architectures subject to undefined behaviour, however? The signed overflow case mentioned, for example. Sure, some of it is implementation-defined, but in practice you need to write ultra-portable code anyway in order for your compiler not to pull the rug out underneath you.
- scaramanga 5y agoThe behaviour of signed integer overflow is undefined, but only if it actually overflows, and whether it overflows or not can be based on the widths of types which are implementation-defined, so there is a link between the two things. Many "correct" programs rely on undefined behaviour for optimizations while the authors knowingly assert (or assume) that the undefined behaviour doesn't actually occur. So the question is, if you are writing non-portable code for a specific environment, is a UB that actually triggers on your environment "non-portability" or is it a "bug"? I think most people would define that as being a bug. Edit: Okay, bad example cos you could maybe use int_leastN_t or something in that example to document the assumptions... But you don't always have control over types, and there may be multiple constraints, etc..
- thesuperbigfrog 5y ago>> in certain circles there is this weird fetishitization of portability, placing it on the highest pedestal as a metric of quality. It's not a fetish if you have ever ported legacy code that was not written with potability in mind. "ints are always 32-bit and can be used to store pointers with a simple cast" may have worked when the legacy program was written, but it sure makes porting it a pain.
- nyanpasu64 5y agoAnd `unsigned long` can store pointers just fine on Linux 32, Linux 64, Windows x86-32, and MSYS2 64... but not Windows x86-64. https://github.com/cc65/cc65/issues/1680#issuecomment-1046412397 https://github.com/cc65/cc65/issues/1680#issuecomment-104641...
- loeg 5y ago32-bit 'long' on a 64-bit pointer platform is kind of a bizarre choice by Microsoft. Technically allowed by the C abstract machine, of course.
- bombcar 5y agoArguably on a system where you can address 8 bit byte, 16 bit word, 32 bit dword, and 64 bit qword having char, int, long, and long long all be different sizes makes sense (and gives the programmer control) - especially if before they were assumed to be shorter. A program with 32bit longs will probably work fine most of the time, and save memory while doing it (which can matter for cache hits/misses).
- leetcrew 5y agoint is the same width as long in msvc though. if the width of an integral type is remotely important to the correctness of your program, you should really be using stdint.h types to document that intention, regardless of whether you care about portability.
- 5y ago
- xemdetia 5y agoI would say most modern code is not the kind of code written with the absurd platform assumptions that old code used to do. There's not magic addresses you have to know to talk to hardware, there's no implicit memory segmentation/memory looping, and so on. Ever since most modern OSs try to prevent direct access or randomize address spaces and so on it just is hard to write code that is insane like the way we were. So the question is are you contesting the POSIX defined behaviour over using more logical interfaces from the OS or the wild west where people were hacking around broken, platform-specific features and often broken or awkward system libraries or just the more modern case where people use the standard interface instead of a more performant one. In the latter case I agree I wish there was a more 'nice' way of doing more dynamic and efficient feature detection without making simple C programs crazy complex.
- Someone 5y agoI think it also helps that modern hardware is a lot less diverse. Most of the tools only run on systems that are little endian, where NULL is zero, chars are 8 bits, ints are two’s complement and silently wrap around, floats are 32 bits IEEE 754, etc, so code that erroneously assumes those to be true in theory isn’t portable, but in practice is. And newer C standards code may even unbreak such code. Ints already are two’s complement in the latest version of C++ and will be in the next version of C, for example.
- isomel 5y ago> code that erroneously assumes those to be true in theory isn’t portable, but in practice is. Be careful about undefined behaviour still. Even if your architecture have defined semantic, the compiler might still not assume them.
- dahfizz 5y ago> I would say most modern code is not the kind of code written with the absurd platform assumptions that old code used to do. That is a pretty bold claim. I would be surprised if any nontrivial "modern" program would be bug-free on a platform with nonzero NULL, non two's compliment ints, big endian an non IEEE floats. The assumptions we make about the platform just don't feel like assumptions anymore because every machine is the same nowadays.
- LeifCarrotson 5y ago> If a platform specific way of doing something works better in some use-case then there should be no shame in using that. I fully agree, but the real problem is not the limitation to platform-specific logic but the conflation of fundamental requirements and incidental requirements. There's no good way to know when you meant "int" as just a counter of a user's files, or "int" as in a 32-bit bitmask, or "int" as the value of a pointer. For the former, it probably doesn't matter if someone later compiles it for a different architecture, for the latter, if you mean int32_t or uintptr_t, use that!
- dahfizz 5y agoI strongly agree, if only for the readability benefits. Using uintptr_t vs uint64_t vs long long are all technically equivalent, but they convey information to the reader about your intent
- ithinkso 5y agoI love how the concept of 'platform independent' evolved - you would think that it means you can run it anywhere but almost all software that uses 'platform-independent' code is very platform-dependent Because if you make an Electron app it's only logical that because it is platform-independent it can only be run on macOS
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- jltsiren 5y agoI work in bioinformatics, where the underlying technology changes often enough that you don't have to think too much about portability. If a new fundamentally different system emerges, my old code will probably be obsolete before I have to think about supporting it on the new system. I was around during the 32-bit/64-bit transition (which was painful), and I've been porting code targeting x86 to ARM (which is usually not). Here are some thoughts I've had about portability and system features: Your code includes your build system and dependency management. If they are not portable, your code is not portable. I'm a language descriptivist. A standard is an imperfect attempt at describing a language. When the compiler and the standard disagree, the compiler is right, because it decides what the code will actually do. OpenMP is an essential part of C/C++. Compilers that don't support it can't compile code that claims to be C/C++. There is no point in pretending that you support systems you don't regularly use. In my case, portability means supporting Linux and macOS, x86 and ARM, GCC and Clang, but not in all combinations. Portability, simplicity, and performance form a triangle. You can choose two and lose the third, or you can make compromises between them. Pointers are 64-bit. If they are not, you need a lot of workarounds for handling real data, because size_t is too small. Computers are little-endian, because that enables all kinds of convenience features such as using data from memory-mapped files directly. Compilers should warn you if you use integer types of platform-dependent width, unless the width is required to be the same as pointer width. And except as argc and related variables.
- gnufx 5y agoI do research computing support, and bioinformatics has long been thought in my circles the nightmare area to support (perhaps supplanted by machine learning these days). To pick up some of that, compiler maintainers obviously disagree about the compiler always being right (which one?), and I'm baffled by the requirement for a compiler to support OpenMP (which version) to be considered C, especially if you're dealing with, say, embedded systems for bioinformatics data acquisition, for instance. I've successfully claimed to support systems I'd never used in high-profile projects (particularly when the architecture and operating system landscape was rather more interesting); I couldn't just tell the structural biology users there was no point supporting their hardware. I currently support a GPU-centric POWER9 system, but I hadn't actually used POWER in the years I'd been building packages for it (and ARM).
- adonovan 5y agoWell said. It's possible to write shell scripts that are portable between Mac and Linux, but it takes years to learn all the places where the semantics differ. For example, there's no portable way to call sed with both -e and -i flags. In many cases it's better to say "this script assumes Linux" (and perhaps use Docker to simulate Linux) than to waste time supporting another platform.
- Shorel 5y agoFrom a technical point of view, we are in agreement. The issue is when platform-specific code ties your business logic to a particular vendor API, and then this vendor milks your company for profit.