7 ms·
I think it's about time to abandon C language entirely.
by po1nt 5y ago
I think it's about time to abandon C language entirely.
- Asooka 5y agoSometimes I do wonder if all these UB optimisations aren't pushed by people aiming to make C and C++ unusable, so that people will be forced to move to other languages.
- jjtheblunt 5y agoUB = Undefined Behavior ?
- MobiusHorizons 5y agocorrect. In my experience a focus on UB (often actually said U.B.) tends to come from the C++ community, although a lot of it trickles down to the C community as well. I can recommend watching a few talks from C++ conferences. I especially enjoyed ones by Matt Godbolt, and Miro Knejp.
- ncmncm 5y agoNot correct. Most UB is the same in C and C++. If you disallowed optimizations based on UB, it might have more effect on C++ programs, just because C++ tends to more deeply inlined abstractions that can benefit more from them. But those don't tend to need much attention. The cases people worry about are more common in C code, just because the concept of type is less important in C.
- MobiusHorizons 5y agoHow is this not correct? UB = Undefined Behavior. Or are you saying that UB is not from the C++ community? That could certainly be true, I am just describing the situation as I see it where C++ disallows more types of casting or reinterpreting than C does (even if compilers allow it). One salient example I heard was that the only way to legally read the bits of a float in C++ is to memcpy the float onto an integer type. whereas in C its legal (I believe by using a union).
- ncmncm 5y agoNope! Same. BTW the memcpy is always optimized out, so you might as well; then it's totes portable, C or C++. You can always build up an object (int, float, struct) from char values. Technically they are supposed to have come from another value of the same type, but the compiler can't really tell where the bytes came from, so has to assume they must have come from there. C does have a thing where a void pointer can be copied into any other pointer, without a cast, and operations with the typed pointer are OK. Technically, the pointer value is supposed to have been copied to the void pointer from the same type, but realloc has to work. Note, realloc does give you alignment guarantees you don't get from pointers to random things. Nothing else is portable. Unions, other pointer casting, all is UB unless your compiler extends the definition. So, Gcc has an extension to make unions, used in a certain way, well-defined. Probably Clang copies that. You would have to look up exactly what. But the memcpy hack works in all compilers. You won't use it often enough for the extra verbosity to be a problem.
- jjtheblunt 5y agoIn C you're free to get the address of the float (presuming it's not in a register) and cast that address to a pointer to an array of char, which doesn't copy anything, just re-decrees, from that point on, to the code generator of the compiler what assembly code is generated.
- ncmncm 5y agoRight, I should not have said you have to memcpy. You can poke bytes any way you like, in any order you like. But! memcpy is known to compiler optimizers, so is more reliably optimized away.
- rightbyte 5y agoIt has come to my mind too. It is user hostile none the less, blaming the user for writing incorrect but intuitive code. The Stackoverflow mindset? My favourite is how "x + 1 < x" is optimized away for signed ...
- mhh__ 5y agoIf a warning is issued in that case I'm tempted to say it's fair game. If you are sure it'd safe the compiler has extremely well established ways of telling it (i.e. assume or unreachable)
- Asooka 5y agoI wouldn't call it fair game, not least because nobody reads warnings. My central objection is that it's not what C is meant to be. C was made to write Unix, it was specifically created to be halfway between a portable macro assembler and a high-level language. That is a useful language that fills a particular niche. That is what C was for many years and a lot of code was written with that behaviour in mind. It can be argued that compilers which change semantics from what people intended are downright irresponsible given the foundational role that C has. All this wouldn't be an issue if C were just some application language, but it's what all of computing is built on. It really should be simple by default and without adding more footguns than what directly programming in assembly gives you. I wouldn't mind if all the assumptions-based optimisations were made opt-in. They are obviously useful in some way, but they're impossible to allow globally in a large legacy codebase. Which is pretty much every C codebase.
- ncmncm 5y agoThere is probably more than a million times as much C code that is not Unix as code that is. We could chuck in all the other OSes, and all the RTOSes besides, without changing the statement.
- alerighi 5y agoThat is the fault of compilers, not the language. That thing should rise at maximum a warning. A compiler should not change the semantic of the code, even if the code relies on undefined/unspecified behavior. I don't get how someone thought that it is a good idea to silently remove apparently unreachable code.
- bsder 5y agoThat's a touch unfair. The problem is that C is sufficiently primitive that optimizing it is effectively trying infer structure backwards because the language doesn't specify it. For-loops are a great example. Why are we even discussing about a "loop index"? Because we need to iterate over an array, string, etc. and "length" isn't something stored with the data structure so the compiler can't do the loop for you. The real question is probably more along the lines of "Should the C standard start pinning things down more than it does?" The answer is probably yes, but it's not straightforward to do. Look at just how much verbiage it took to create a decent memory model. And, still, using atomics in C (as opposed to C++) is brutal and the compiler can't help you very much.
- vyodaiken 5y agoYour argument would be more compelling if programming languages with higher level iteration primitives were significantly more optimizable than C. The underlying processor architectures have loop indexes. Just pretending you can do applicative programming doesn't mean you can. C is very adaptable - even to GPUs. Also, I have yet to see that decent memory model.
- SubjectToChange 5y ago> C is very adaptable - even to GPUs. Can you expand on this? I've never heard of someone seriously running actual C on a GPU.
- MobiusHorizons 5y agoI'm curious what you would replace it with? I can't think of anything actually suitable for most of the low-level operating systems / embedded level things that use C. I know people recommend rust for this kind of thing, but Rust really isn't appropriate in a lot of cases, especially when dealing with microcontrollers not supported by llvm (ie PIC, 8051 off the top of my head). This may be changing, but I was also under the impression that Rust can't easily produce as small binaries as C can.
- yjftsjthsd-h 5y agoI'd nominate Pascal (which has been used for OS dev before) and Ada. Not 100% sure how broad their support is for different hardware, but it also seems like adding new platforms to an existing toolchain is less work than inventing a new language while still benefiting from being not-C.
- remexre 5y agoI'm partial to Forth, but I think "get rid of C" is a bit of an extreme opinion...
- gHosts 5y agoD
- kjs3 5y agoAs an alternative in your use case, there was a pretty decent Modula-2 compiler for the 8051 (Mod51). It's a small, safe language and a reasonable fit for embedded architectures. It is a Wirth-ian BEGIN...END language which for some people means it has cooties, but I wrote a some useful stuff in it a long time ago and it was pretty painless, as such things go. There's even some standardization around Modula-2 in the embedded world (IEC 61311-3 ST). Unfortunately, I don't think Mod51 is sold any more; C won in that world.
- MobiusHorizons 5y agovery interesting
- kjs3 5y agoAs long as you write compilers for all of the platforms which currently only have C language production quality compilers. That includes porting the whole development ecosystem for those platforms (like libraries) to whatever NextNewShiny language you deem worthy. We'll wait...