Ranter
Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Comments
-
theuser47814yNot sure where that AMD vs Intel thing comes from, that was new to me. Intel is very much the gaming CPU, with AMD doing the occasional jabs.
Porn in incognito is indeed very useful. -
@theuser also not sure about thaz amd vs intel thing, the only thing i ever heard about this was around the year 2000-2005 when amd and intel with the same clock speeds allegedly differed in amd being better at multitasking (and thus work stuff, so the other way around)
-
Geoxion9014yC is outdated, though. The problem is that too many people are still using it 😉
No seriously, don't start new projects in C -
Geoxion9014y@Demolishun Linux is adding support for non-C code, though. Most notably Rust support!
That's pretty cool 💪 -
Outdated... A sentence containing outdated and a programming language is simply pointless.
-
Geoxion9014y@Demolishun I know... Why do you think that I think otherwise?
I'm not saying that you can't write great software in C. I'm saying that there are better tools nowadays. Rust is the main one.
And even though it's early days, something like Zig seems like a big improvement over C as well. (I'll take Rust over Zig, still) -
@Geoxion What we need is something builds upon C and keeps all the great things that C provided, allows zero cost abstraction, is able to be backward compatible, supports generic programming allowing multiple programming styles, has fine control of the abi, and continues to grow and change according to the needs of the programmer.
-
Geoxion9014y@IntrusionCM If that were true, then it would be reasonable to start new projects in Algol 58, BCPL or, even more modern, C# 1.0
Most languages that exist are outdated -
Geoxion9014y@Demolishun One of the ways to improve is to get rid of the bad stuff and keep the good stuff. Sounds good right?
Except... That breaks backwards compatibility.
C++ is the greatest victim of this. It tries to be a bit compatible with C and that's where most of the bad stuff still lives. -
@Geoxion as long as projects exist which need to be migrated or extended, the language is alive.
And to not start a new project because the language is outdated...
If you take away make, M4, C, COBOL, Posix SH, perl ... really everything wouldn't work.
Why not start a project in C# 1.0? Just for fun and as a learning experience?
We've talked about C before.... Not obscure things - but the statement stands: Just because a language is old doesn't mean it shouldn't be used.
Many new languages like Rust are still struggling to become stable - it takes time for languages to settle -
Geoxion9014y@Demolishun
C is weakly typed.
Management of ownership and lifetimes is left to the programmer.
Have you ever used strings in C?
Absence of modules/namespacing.
Insane preprocessor.
Normal looking operations can be UB.
No warnings for doing unsafe memory access.
Every one of these items is a deep rabbit hole. -
Geoxion9014y@IntrusionCM using old stuff for fun and to learn from is very good! I would encourage it.
And being outdated doesn't mean it's dead. Even COBOL isn't dead yet. Some code that is running now will probably still run in a hundred years.
But I say that you shouldn't start NEW (non-toy) projects in an outdated language. I'm also not saying that everything must be rewritten. That's just not feasible.
Btw, Rust has been stable since 2015. Code that compiled then will still compile now. Nice recent discussion: https://reddit.com/r/rust/... -
@Geoxion I written code in C and C like languages for over 20 years. Most of what you mentioned are features of C that are required for doing any kind of embedded work. C doesn't babysit you.
1. You need absolute control of memory management in embedded platforms. In game programming on consoles you often need to perform in place new (in C++) to keep from fragmenting memory. You also need to be able to point to memory locations such as graphics card addresses.
2. Often in C and C++ you have to redefine what a type means. This is often required especially in communication protocols.
3. Provide an example of a normal operation that is UB. The only time I have seen this even looking like this was happening when someone didn't understand what was happening in a macro.
4. What does "insane preprocessor" mean?
Summoning a C expert (Klaatu Barada Nikto):
@fast-nop -
@Geoxion Rust isn't stable.
And for many reasons I do not use reddit.
Planet Mozilla is a good source, since many of the core devs blogs are linked there as Rust started at Mozilla.
Rust still evolves and still struggles with the compiler and LLVM - since burrowing is hard.
Stability is more than "core language spec". Rust is still a hot glowing iron... -
@Demolishun At your service. ^^
Well yeah, C is great for people who understand hardware at raw byte level and want to eek out what they can.
I'm doing bare metal stuff and am amazed that I only need a minimum of startup assembly for booting. I also like the preprocessor, that's one of the great things about C. I also do C stuff on application level where performance matters. Even Android has the magnificent NDK that gives you a decent C/C++ compiler.
However, it's also true that there's WAY too much UB that ought to have been IB instead. The standards comittee was lazy, just slapped UB on everything and hadn't anticipated sadistic compiler writers like the GCC team.
I mean, why is signed int overflow UB? That's insane because all machines today use 2's complement. Had it been IB, then we wouldn't need a compiler switch for no strict overflow. -
@IntrusionCM Rust is completely unusable at present. The core standard library sucks, you have to use crates for everything - only that there are dozens of them, dependency hell all over, and projects from five years ago don't even compile anymore.
And it has no ISO standard so that you can't force a compiler to use the non-existing say Rust standard 2015. Total bummer. Also, only one compiler "vendor" so that the language is basically at their whim. Nobody wants shit like Python2 to Python3 in real projects.
That's also why 99.99% of devs say Rust is super hot (if only because the compiler doesn't let you do anything non-trivial without hoops), and 97% of them don't actually use it in real projects.
Rust is where C++ was when Boost was a thing, i.e. before they included most of the useful stuff into the STL. They need to get their shit together. -
Geoxion9014y@Demolishun
1. I know, I do embedded development. Doing unsafe memory stuff is sometimes necessary. But that doesn't mean that you should be able to do it anywhere you want without warning. In Rust you need to tag that code with 'unsafe', a bit like C# does with pointers.
2. Redefine what a type means? Don't exactly know what you mean by that, but it sounds very messy and a limitation where the type system is not expressive enough. The functional languages are very good with this kind of stuff.
3. Ever used a union and read it as a value that wasn't used to assign it (i.e. converting)? That's UB. More here: https://stackoverflow.com/questions...
4. It's usable, sure, but so many things can go wrong: https://stackoverflow.com/questions... -
@Geoxion Item 3 is not true for C. Type punning through unions is an approved method (besides memcpy). However, it is UB for C++.
-
@Fast-Nop C++ doesn't officially support this. But the major C++ compilers fall back to the C interpretation for puning. There may be a flag to stop this though. I know all our canbus libraries use this in our c++ projects. It will never go away.
-
Where do people get the idea that any programming is safe? Especially in embedded systems? That idea is foreign to me. If you are concerned about memory issues then valgrind the shit outa your code.
-
@Geoxion Interfacing with hardware and lots of libraries you get void pointers. I see this more so in C code, but run into this in C++ as well.
You can also end up with binary blobs. Being able to define that blob in different ways is advantageous. This is related to puning. -
@Demolishun I get the idea of Rust, that it's better to have 10% "unsafe" code to review than having 100% unsafe. However, when you can't even do trivial stuff like double linked lists without advanced Rust knowledge, that's an issue IMO.
Theory: devs will jump through hoops of advanced Rust knowledge to do that.
Reality: devs have no time to do that and will slap "unsafe" wherever Rust gets in the way, negating the advantages as they go. -
Geoxion9014y@Demolishun pretty good online free book about some low level stuff in Rust: https://doc.rust-lang.org/nomicon/...
-
@Demolishun Actually, I don't use void pointers for that because memory mapped IO and register settings do have proper types. It's more for memory block operations like calculating a CRC and the like.
-
Geoxion9014y@Fast-Nop the doubly linked list is more a meme than anything practical. When is the last time you genuinely wrote one?
If you really need one, just grab the standard one:
https://doc.rust-lang.org/std/...
It's probably better than any implementation you'd write in a whim.
But yeah, according to Rust's rules you need unsafe for that. -
@Geoxion In my side project, I do need a double linked list. However, the point is that an elementary data structure shouldn't require advanced language knowledge or hacks.
Other stuff like "single producer, single consumer lockless queue" is really common, and that doesn't work without "unsafe" either. Think any time you hand over data from interrupt to application, or even a ring buffer between threads. -
-
@Fast-Nop Aren't tree structures really similar to doubly linked lists? I use those quite a bit.
I use doubly linked lists when a vector doesn't make sense. Of course I use the ones from libraries and am not writing them from scratch. I do write tree structures from scratch though. -
@Demolishun I don't think so because a tree has only downwards links, i.e. you don't reference the same child node from two parent nodes. That would rather be a graph.
As long as you only have one source link to your destination, Rust's ownership model won't interfere. -
Geoxion9014y@Fast-Nop indeed, you need to use unsafe for that at some point. (Well, except for when using atomics or mutexes) But you make it sound like you're breaking some sacred oath. You aren't.
The point is that Rust also gives you a lot of machinery to abstract it all away. That way the unsafe only resides in another library (or part within the same project) and not in your business logic code. Way easier to review. This of course requires that library to be sound.
For example, I made a bootloader and used some assembly to jump to the user application. Very unsafe. But only that part is unsafe. If I want to hunt for memory problems, I only have to look there in my bootloader. Everything else is guaranteed to be safe. -
@Geoxion The thing is, you use global data structures a lot in embedded, though of course scoped as static where possible. That's because malloc/free isn't an option since the system would assemble state under the hood, making it untestable. Just think of memory fragmentation when your virtual address space is your physical one because there's no MMU.
-
Geoxion9014y@Fast-Nop since I've got half a meg ram free, I do have a heap. Makes string manipulation a lot easier. But it's only for short-lived objects.
Sharing data happens a lot yeah. I want to refactor to the RTIC library. It's really cool, you should take a look. Even if you're not gonna use it, it has a lot of interesting ideas that came from the academic world: https://rtic.rs/0.5/book/en/ -
@Geoxion If you use malloc/free a lot, don't expect stable operation for extended time. If that isn't required, it's OK.
Otherwise, that's why I allocate temporary objects on the stack, not the heap, and use stack analysis to make sure there's no overflow. -
@Fast-Nop lolol no, that would be @12bitfloat. I'm the generalist.
I've said it before and I'll say it again - the entire point of Rust is to make as many things explicit as possible so that automated tools can help you with them. If there's anything that's complicated in a Rust program, it's because the underlying concept it's trying to model is complicated in some way that's usually being hidden from you (usually, that is. Rust isn't perfect and can't express everything, naturally).
Cyclic ownership is inherently complicated. It confuses the living fuck out of most pointer analysis passes in compilers. In Rust you have to explicitly tell the compiler to shut up because it's geared to making static guarantees, if it just passed on an actually difficult static analysis problem like circular ownership it wouldn't be a very good analyzer.
Doubly linked list is actually not a trivial data structure - it's trivial from a throwaway C/C++ implementation point of view but not from a memory and lifetime ordering point of view. And again, such things are generally rare and mostly wrapped inside crates anyway. If you're in the business of writing complicated high performance data structures, most of what you'll be worried about in Rust is the same as in C/C++, it's just written down explicitly.
Add to this to the many times it saves you from circular ownership when you should actually not have it - entirely subjective experience, but the static analysis made me rethink my code and rewrite it to be better so, so many times.
Also, I do agree that the incremental benefits over deployed C/C++ code and existing engineers might not work out economically for companies to use Rust, but it's also untrue that nobody's using it. It's still a very young language and expecting it to appreciably displace established industry behemoths is a bit much. -
@Fast-Nop Also, compiling and working with projects is actually a pleasure - the cargo build system that I suspect is the actual reason so many people like Rust. You complain about dependencies and crates - look at the other side. Try building a Discord bot or pretty much anything else in Rust, it's stupidly easy because the ecosystem encourages sharing and most well written crates follow semantic versioning. It's almost Python-with-conda levels of ease, which is nuts for a systems language. And it's insanely viable - I slapped together a discord bot in about two hours, complete with multithreaded Redis integration and a command interpreter with a decently complicated BNF grammar, and it's running on a resource constrained server (which timed out for the same bot in Python and Haskell) serving about 25 discord servers. The best part? I got the bot to build on my *phone* (via termux) and it worked just fine with no code changes whatsoever. An absolute pleasure.
Sure your code is dependent on someone else - but that's only a problem if the probability of it breaking times the cost is more than the cost of doing it myself. In my experience, that isn't the case (and despite the grumblings, it largely isn't the case for the JS ecosystem either). Not everything is or needs to be laboriously specified and tested government regulation compliant code (which also largely operates on the if it ain't broke and we have the money to do it, why fix it? approach rather than the best engineering tools anyway, at least in my experience).
Also you can't really say "not compiling code from 2015" is a problem - I wouldn't expect C to compile code from when it was being developed at Bell labs initially either. Rust 1.0 *is* a stable compiler target. -
@RememberMe Well I do have code from the mid-90s that I wrote for MS-DOS, and it still compiles if I give C89 as standard. In my company, we have projects from 10 years go that still need minor updates. Rust's crates system doesn't provide that, especially because of the anaemic standard lib. It's brittle like NPM.
But otherwise, I've noticed that there are different approaches to programming in general. One is to abstract the hardware (and reality) away as much as possible. That's not mine. Like all C programmers, I actually think in assembly, but accept a portable macro assembler. That even shows when I do JS - you won't see frameworks and shit, but you can be sure that it will be efficient. -
@RememberMe Btw., just saying, I sometimes wish I had you in my team because that would yield tech discussions (and outcomes) worth their time. ^^
-
@Fast-Nop C was initially developed in 1971 or something. C89 is a full 18 years after that, and we're 31 years from that standard now. Rust 1.0 happened in 2018 I believe? That's 2 years. Legacy code doesn't really exist meaningfully because the language isn't old enough for it :p
And with how Rust projects are specified I don't see why they wouldn't build exactly the same way 10 years later - the build tool takes language and crate versions into account. I've had no problems building older versions of code with older crates, cargo dependency checking usually makes everything work fine.
It's also a function of what you do with it - C usually doesn't get used with fast moving, stuff-changes-every-day projects while JS does. Little wonder that JS "breaks" more often. I'm willing to bet that 10 years old code you have doesn't connect to a ton of DBs, have to process stuff fast on new processors, or use evolving networking standards. Different use cases, different strengths.
I agree with manual stuff when what I'm doing is not too complicated, and actually I write a lot of C too when I want to work with hardware - I don't have any problem with it (though it's generally because both Xilinx and Intel/Altera tools support or generate C/C++ only). Been trying to automate bootstrapping Rust for Xilinx tools, oh well, someday.
For complicated hardware stuff I would actually automate it, either in a higher level language or via an automated programming environment. You usually get better performance that way, not worse (consider eg. a FFT for a cluster - it's very very hard for manual to do better than a well written C lib or something, but automated tools optimize taking the actual cluster architecture into account). -
@Fast-Nop hey, thanks, I think I'd learn a lot from you :) I tend to get carried away by new stuff a bit too often lol.
-
Geoxion9014yOne last thing, C does actually abstract the hardware with the C abstract machine model.
https://queue.acm.org/detail.cfm/...
Nice article. "Your computer is not a fast PDP11"
A typical bouba coder:
- thinks a kilobyte contains 1024 bytes
- thinks Object.assign clones an object
- codes in react.js, thinks he knows reactive programming
- “amd is better for games, intel is better for work”
- thinks that the main advantage of ssh is that you don’t need to enter your password manually
- watches porn in incognito mode
- “crapple”
- “uhm, is it immutable?”
- thinks “persistent” means saved to local storage
- thinks designer is an inferior job because “they only draw shapes”
- thinks good accessibility is when the tab key works
- “All non-mechanical keyboards are trash”
- “C is outdated and nobody uses it anymore”
- “Zuck quit uni and now he’s a billionaire, everybody should quit”
- thinks “pointer” is a shape of the cursor
rant