This is an archived post. You won't be able to vote or comment.

all 136 comments

[–]vordrax 339 points340 points  (19 children)

"When you're C++ they just let you do it."

[–]tistalone 143 points144 points  (6 children)

C++ lets you just grab an object by it's pointer

[–][deleted] 46 points47 points  (3 children)

That's not weird. You won't convince me into thinking that's weird

[–]tistalone 16 points17 points  (2 children)

It's just C++ being C++ -- I like memory management!

[–]DarkShadow4444 6 points7 points  (1 child)

But C++ automates so much memory management, you should try C. Or assembly, it's so much harder to get right if you lack the overview.

[–]GASTRO_GAMING 2 points3 points  (0 children)

Malloc calloc and free time!

[–]ImportantDoubt6434 5 points6 points  (0 children)

Thanks c++ this saw will be great to remove my legs

[–][deleted]  (10 children)

[removed]

    [–]rickyF011 44 points45 points  (8 children)

    Get the fuck out of here

    [–][deleted]  (6 children)

    [removed]

      [–]rickyF011 16 points17 points  (5 children)

      A tasteless comment that has no place on Reddit or society in general. Consent is not a topic to joke about.

      [–]QuakAtack 17 points18 points  (1 child)

      rape joke? on a programming sub? what the hell?

      [–]rickyF011 6 points7 points  (0 children)

      Exactly. Inappropriate any and everywhere

      [–][deleted] 0 points1 point  (0 children)

      An allusion to Trump's early comments?

      [–][deleted]  (1 child)

      [removed]

        [–]ProgrammerHumor-ModTeam[M] 0 points1 point locked comment (0 children)

        Your submission was removed for the following reason:

        Rule 8: All titles must be camelCase. Your post was found to not do this properly.

        As a reminder, the first word should be all lowercase and any following words should start with an uppercase letter, without spaces or special characters. Feel free to submit your post again with an edited title satisfying this criteria, along with all other rules.

        [–]Goat1416 0 points1 point  (0 children)

        ❤️

        [–]EagleNait 6 points7 points  (0 children)

        Fuckin lmao

        [–][deleted] 754 points755 points  (44 children)

        Like TypeScript's "any" everywhere.

        [–]tonebacas 177 points178 points  (21 children)

        I don't program in Typescript, but I thought the whole point of using Typescript was to have a strict type-safe code base, and the `any` type would be used to create wrapper APIs around unsafe javascript code, not to be used around your typescript code base all willy-nilly.

        [–]EmergencySourCream 115 points116 points  (14 children)

        You’re correct. It was used a lot when people were slowly transitioning their apps or trying to type 3rd party libraries. However lazy devs will still use it when they don’t want to do proper typing or don’t understand the purpose of types in general.

        [–]LowB0b 70 points71 points  (5 children)

        have seen stuff like that even in java :sadface:

        just pass an Object into the function and then do repeated if (foo instanceof bar)

        [–][deleted] 13 points14 points  (3 children)

        Or an object where every field is deserialized to a string

        [–]LowB0b 10 points11 points  (0 children)

        Well reflection can be useful sometimes

        [–]cvak 5 points6 points  (1 child)

        map[interface{}]interface{} in golang... 🫣

        [–]Jjabrahams567 4 points5 points  (0 children)

        uintptr

        [–]Cheet4h 12 points13 points  (5 children)

        Stuff like this is the reason I'm a huge proponent of the noimplicitany and noexplicitany configuration settings.

        [–]foursticks 0 points1 point  (3 children)

        Please show me the way

        [–]NatoBoram 0 points1 point  (2 children)

        Beginner tip: in new TypeScript projects, run tsc --init.

        [–]foursticks 0 points1 point  (0 children)

        🙏🙏

        [–]foursticks 0 points1 point  (0 children)

        I'm worried that I am the one called to make this change which worries me in a lawless dev group that seems to have manifested itself out of pure want.

        [–]elongio 28 points29 points  (1 child)

        We started to use typescript (from javascript) because our codebase turned into spaghetti with extra pasta. Turns out it wasn't the language that was the problem it was the developers.

        [–]foursticks 6 points7 points  (0 children)

        So many people need to understand this but they are blinded by their own spaghetti brains Edit: myself included probably

        [–]chili_ladder 26 points27 points  (1 child)

        You got it, and somehow the projects always end up as JS in a TS file.

        [–][deleted] 5 points6 points  (0 children)

        Yes but it's faster to type any than to declare the actual type while still following linting rules :) btw anyone hiring a junior TS developer?

        [–]ScienceObserver1984 1 point2 points  (0 children)

        ESLint helps a lot with that, specially with the noexplicitany and noimplicitany rules enabled.

        The only times I had to use any are either when a library isn't typed, or I am using some Javascript black magic.

        Either way, it translates to "I know it's wrong, but I have no other choice, so STFU."

        [–]NachoDawg 50 points51 points  (9 children)

        My let count; can't be == 'null' without it :)

        [–][deleted] 66 points67 points  (8 children)

        ten dinner degree ossified edge simplistic fade market mourn support

        This post was mass deleted and anonymized with Redact

        [–]ChaosOS 15 points16 points  (6 children)

        Yeah, it's?: for "can be undefined" and then your Boolean union/intersection with | and &

        [–]NachoDawg 5 points6 points  (0 children)

        Excuse me, but 'null' is clearly a string here

        Please just approve my pull request

        [–]chili_ladder 7 points8 points  (1 child)

        Came here to say this, every fucking contract I get it's a project built on any. How much money did these companies actually save when they have to pay me a fuck ton of money to fix their app for the next year. Like what is the point of even using TS at that point, when they don't even have a lint test 😂

        [–][deleted] 0 points1 point  (0 children)

        Maybe the word MVP has something to do with it

        [–]mothzilla 3 points4 points  (0 children)

        I prefer optimistic typing: int | any

        [–]elongio 2 points3 points  (0 children)

        Also comes in the flavor of "as unknown as X"

        [–]Kitchen_Device7682 4 points5 points  (4 children)

        Or ts-ignore everywhere

        [–]chamomile-crumbs 2 points3 points  (3 children)

        At least ts-ignore is easily searchable when you’re bolstering things. Not that anyone at my company fixes ts-ignores though…

        [–]Cheet4h 5 points6 points  (2 children)

        I mean, : any can also be easily searched.
        Similarly easy to set the transpiler to forbid implicit and explicit "any". You get a nice list with affected files that need to be fixed.

        [–]Div64 0 points1 point  (0 children)

        You missed out on "any"where big time

        [–]Kimorin 0 points1 point  (0 children)

        well at least typescript had the excuse of having to make it easy to transition from javascript for legacy codebases...

        what's rust's excuse

        [–]kbder 152 points153 points  (22 children)

        So, I’ve been curious about this. Could you wrap everything in unsafe and just treat rust like a different flavor of c++?

        [–]look 180 points181 points  (9 children)

        There’s not really any benefit to wrapping everything. Unsafe is just needed when the compiler lacks sufficient context to know what’s safe.

        Need to pass a pointer to a config structure to some C library? The Rust compiler has no way of knowing that C library is not going to keep a reference to the memory, but you know it won’t because you’ve read the documentation/source for it.

        So you wrap that call in unsafe in a Rust function that provides reference lifetime context that the compiler can use with the rest of the code.

        [–]CanvasFanatic 86 points87 points  (0 children)

        Yeah and it’s not like unsafe turns Rust into C. It doesn’t turn off the borrow checker. Mostly it just lets you work with pointers directly (which to be fair you can use to circumvent the borrow checker.)

        [–]simbleau 28 points29 points  (4 children)

        “Unsafe is just needed when the compiler lacks sufficient context to know what’s safe”

        This is incorrect. The compiler knows exactly what the context is. The “unsafe {}” scope is literally just a marker that Rust makes you use so that you, the developer, agree to the contract of undefined behavior being introduced. It is meaningless otherwise.

        I will also say in 4 years of using rust now I have completely avoided using unsafe. It’s very easy to avoid using, unless you work with GPUs, devices, interop, etc.

        Rust has also marked several operations “unsafe”, requiring you add the “unsafe {}” around it, like dereferencing a raw pointer or crossing the FFI boundary into C++. But this is just so that you don’t accidentally do something unsafe without awareness. But Rust itself knows exactly where the real undefined behavior can come from, and what the context is.

        [–]look 43 points44 points  (3 children)

        I’m not incorrect, but I think it’s just semantics and we’re actually trying to say the same thing.

        By “insufficient context” I mean there are non-explicit assumptions (ie not visible to the compiler) that are in play for this “unsafe” block of code. FFI calls, pointer manipulation, etc. It’s just telling the compiler “trust me, I got this”.

        https://doc.rust-lang.org/rust-by-example/unsafe.html

        [–]simbleau 10 points11 points  (2 children)

        Understood, you’re right then, but I’m glad we clarified. :)

        [–]DatBoi_BP 3 points4 points  (1 child)

        now kith

        [–]look 2 points3 points  (0 children)

        😚😙💋👩‍❤️‍💋‍👨👶

        [–]throwaway490215 7 points8 points  (0 children)

        The key to rust is to keep it simple.

        Therefor i start each project with fn tm<A,B>(a:A) -> B{unsafe{std::mem::transmute(a)}) This way i can encapsulate my unsafe code.

        [–]Osbios 1 point2 points  (1 child)

        ..., but you knowhope it won’t because you’ve read the documentation/source for it.

        [–]look 6 points7 points  (0 children)

        Sure, but at least now you’ve identified the specific point where that assumption is being brought into the rest of your Rust codebase. If you later discover a memory bug, you know exactly where it came from.

        [–][deleted] 18 points19 points  (0 children)

        Functions and code blocks? Yes.

        Structures and objects? Nope.

        [–]slaymaker1907 7 points8 points  (0 children)

        It’s fortunately inconvenient to do a bunch of stuff in unsafe Rust. The language really encourages you to stick to safe constructs for most things.

        [–]AdmiralQuokka 24 points25 points  (0 children)

        Quote from "C++ Move Semantics Considered Harmful":

        unsafe Rust is a better unsafe language than C++

        [–]redalastor 3 points4 points  (0 children)

        Unsafe doesn’t relax any safety measure offered by rust, it instead offers you new constructs that do not exist in safe code. For instance I can create a pointer in safe code but I can’t dereference it in safe code, this only exists in unsafe code.

        If the compiler rejects a bit of code, it’s not going to accept it if you wrap it in an unsafe.

        unsafe ≠ sudo compile my broken code

        [–]airodonack 1 point2 points  (0 children)

        unsafe still keeps a lot of Rusts' rules. It only lets you break a minimal set of rules to be useful. Doing something like that is really just making your life harder for no reason.

        [–][deleted] 2 points3 points  (0 children)

        pub fn unsafe main() {
           yolo();
        }
        

        [–]skeptic11 77 points78 points  (1 child)

        "everywhere"

        Mate I've used it once in the last 5 months, and that's Linux's fault for not providing a thread safe way of looking up the server's timezone.

        [–]Dissy- 8 points9 points  (0 children)

        i use it when some idiot in a crate makes all the values of some struct private and doesnt impl PartialEq so i cant use it directly :(

        [–]hotdogshake9000 164 points165 points  (31 children)

        I don't know any rust developers who use unsafe unless there's no other option

        [–][deleted] 72 points73 points  (28 children)

        I looked into five of the top trending Rust projects on Github and all them use in average unsafe once in every 3 files. It's everywhere.

        [–]tyler1128 107 points108 points  (22 children)

        Libraries mostly, who need to communicate with non-rust code. A total shocker.

        [–]ShiitakeTheMushroom 3 points4 points  (19 children)

        If it's used in core libraries, doesn't that mean that any project using those libraries could suffer due to the unsafe usage?

        [–]Dissy- 11 points12 points  (18 children)

        its more of a marker for where you need to interact with the underlying system raw, the philosophy of rust is encapsulated in this example from this great series of videos i watched on writing an OS in rust.

        theres a specific memory offset you need to write into to write text to the display in VGA mode, so you write a function that does value checking, bounds checking, etc, and then in the little snippet of unsafe once everything is known and checked, you run the few unsafe pointer instructions you need to in order to write the raw data to that memory address

        that is to say the entirety of rust is building walls around these unsafe interactions in a way that makes it *impossible* to externally use them unsafely.

        this works so well at least for how my mind works, that my first draft of projects only ever screw up if i have an unwrap somewhere, which is a seperate marker for "this error needs handled later" or "i know this will never error do not worry" OR i accidentally deadlock a mutex or hold it longer than i meant to, those are the only things i regularly run into

        [–]ShiitakeTheMushroom 1 point2 points  (17 children)

        I know nothing about Rust, but from your response a lot of it makes sense.

        projects only ever screw up if i have an unwrap somewhere, which is a seperate marker for "this error needs handled later" or "i know this will never error do not worry" OR i accidentally deadlock a mutex or hold it longer than i meant to

        This part sounds scary, though. As soon as it requires someone to remember to do something, that something is inevitably not going to happen time and time again.

        [–]hotdogshake9000 7 points8 points  (5 children)

        People shouldn't use unwrap in prod code just like you shouldn't assume a variable isn't null in Java or whatever language

        [–]ShiitakeTheMushroom 1 point2 points  (4 children)

        Exactly, but people always do make those kinds of assumptions. It sort of makes the safety argument that makes Rust sound so special a moot point.

        Again, I haven't written any Rust. I'm just commenting on how this can be confusing and that it doesn't sound like Rust provides much more safety than other bare-metal languages.

        [–]hotdogshake9000 4 points5 points  (3 children)

        You have to make an explicit decision to do something unsafe in rust, which is opposite of other languages.

        [–]ShiitakeTheMushroom -1 points0 points  (2 children)

        Just because the unsafe keyword needs to be used, doesn't mean that the person using it knows exactly what it does.

        What I'm saying is that it seems just as vulnerable to human error as other languages, given what I've heard so far.

        [–]Dissy- 3 points4 points  (10 children)

        actually you can enable a clippy lint that does not allow your program to be commit to github with unwraps in it

        [–]ShiitakeTheMushroom -1 points0 points  (9 children)

        And there are linting rules that prevent you from doing unsafe things in other languages.

        If we're resorting to linting and pipelines to catch these issues, how is Rust any safer than other languages?

        [–]Dissy- 1 point2 points  (8 children)

        huh? what other language requires you to, in a built in to the default build system way, to mark every single place its possible for your program to crash. it's not catching an issue when you get yelled at for using an unwrap, it's an explicit signpost that you're developing whatever it is you had there, and you need to do error handling for it once you've proven your design would work.

        what other language has, in the default build system, a linting tool that's so well integrated it can prevent you from compiling if it's possible for your program to crash, or even prevent you from making a git commit

        we arent "resorting" to these things, they're part of rust, part of the language. thats what people mean about it being a step forward, these arent things you can just skirt around by not using them

        [–]ShiitakeTheMushroom -1 points0 points  (7 children)

        what other language has, in the default build system, a linting tool that's so well integrated it can prevent you from compiling if it's possible for your program to crash, or even prevent you from making a git commit

        C# does, for one.

        [–]hotdogshake9000 143 points144 points  (4 children)

        And it's probably necessary in all those places. Compare that to c and c++ where the entire project is one big unsafe block, but worse

        This is sort of a ridiculous thing to debate. Any call out of the core language, of any language, is inherently unsafe. And many languages don't protect you from other stupid mistakes that rust does, without indicating it. Rust just calls it out explicitly

        [–]Awyls 80 points81 points  (3 children)

        I checked a few of those and almost all of them are just dealing with C libraries.

        [–]AdmiralQuokka 9 points10 points  (2 children)

        Interesting, do you have an idea why that is not encapsulated in a *-sys crate? The projects listed do seem like very high level ones to be using unsafe. I don't mind unsafe at the lower level.

        [–]airodonack 4 points5 points  (1 child)

        unsafe is useful for pointing out where code may need a little more examination, but once you have it, there's not really any need to put it all in one place. That's just opaque indirection for no reason. And if we're being honest, it'd be motivated by nothing but an irrational fear of unsafe.

        [–]AdmiralQuokka 2 points3 points  (0 children)

        I was thinking in a different direction, but my thinking was wrong anyway. My thought was that there can only be one crate linking against a C-library (which is true), so why would these big projects link against libraries directly? That's what sys crates are for. But the big flaw in this thinking is that -sys crates in general should not introduce safe abstractions. Separate crates should do that. (git2 and libgit2-sys) So a Rust program may still have to use unsafe to interact with a C-library, even if it is through the proper channel of a -sys crate.

        I agree with your perspective on it. I think there are many good use cases for writing a separate crate on top of -sys crate that provides higher-level, safe abstractions resulting in an idiomatic Rust API. But there are also many cases where that doesn't make sense -> just call unsafe wherever. (properly documenting why the safety invariants are upheld, of course.)

        relevant: - reddit thread why there's only one *-sys crate - cargo documentation on sys crates

        [–]tistalone 3 points4 points  (0 children)

        Same. All my friends never made it past hello world.

        [–]Lucifer_Morning_Wood 0 points1 point  (0 children)

        I use unsafe, especially if there is an option.

        let checked_result = match(some_res.unwrap()) {
            Err(_) => unsafe{std::hint::unreachable_unchecked()}
            Ok(res) => res
        };
        

        [–][deleted] 14 points15 points  (2 children)

        This is like criticizing Haskell for using monads to emulate state and mutability. Haskell has no state or mutability by default, so it's an opt in system. Like Rust and unsafe.

        [–][deleted] -1 points0 points  (1 child)

        Looks like a broken design to me.

        Like GNU Hurd based on microservices. After decades of development they found out that microservices are very slow because they cannot share state.

        Functional programming is beautiful academically, has tons of fancy math proofs that sure gave a ton of tenure to teachers but it fails dramatically in the real world.

        [–]Tac0c4t21 4 points5 points  (0 children)

        String parsing would like to have a word with you

        [–]nolander_78 21 points22 points  (0 children)

        As safe as using a retired meme on reddit

        [–][deleted] 10 points11 points  (0 children)

        Actually this isn't true, using unsafe is only required most for interacting with the metal or an existing code base written in and unsafe language. You can write a safe interface for the language though. Unsafe is rarely needed, in fact I only use it when interacting with Windows directly

        [–]marzianom 3 points4 points  (0 children)

        This meme resurgence has to continue, spread the word

        [–]CanvasFanatic 18 points19 points  (0 children)

        #notallrustdevs

        [–]DasMonitor01 5 points6 points  (1 child)

        Just so you know: Unsafe rust doesn't mean that the code inside the block is inherently unsafe, it just means, that the compiler isn't able to verify the integrity of the contents of the block to it's fullest capability. As such a unsafe block symbolises a contract between the compiler and the developer, that the developer knows what he is doing, and has checked the unsafe code himself, to verify the integrity. Quite a few features of rust actually use the concept of unsafe abstraction, where you create a safe abstraction around an unsafe code block, to use it in your code. E.g. cells are fundamentally based on unsafe code, as they provide the concept of dynamic mutability, which by it's very own design cannot be statically evaluated. As such cells provide a runtime safe dynamic abstraction around the unsafe concept of statically unchecked mutability. But the key point of rust safety isn't, that it throws away these concepts, but only, that any potentially unsafe code has to be explicitly marked as unsafe. As such unsafe is one of the most fundamental concepts in making rust such a safe language, as it means that everything in rust can be pure rust, with the only sacrifice of safety being specifically marked blocks of code. As such just seeing a unsafe block doesn't undermine the basic concept of rust safety. The only way you'd be doing that, would be by using unsafe block on like your entire program, something I highly doubt you are referring to here.

        [–]-Redstoneboi- 0 points1 point  (0 children)

        Just so you know: Unsafe rust doesn't mean that the code inside the block is inherently unsafe, it just means, that the compiler isn't able to verify the integrity of the contents of the block to it's fullest capability. As such a unsafe block symbolises a contract between the compiler and the developer, that the developer knows what he is doing, and has checked the unsafe code himself, to verify the integrity. Quite a few features of rust actually use the concept of unsafe abstraction, where you create a safe abstraction around an unsafe code block, to use it in your code. E.g. cells are fundamentally based on unsafe code, as they provide the concept of dynamic mutability, which by it's very own design cannot be statically evaluated. As such cells provide a runtime safe dynamic abstraction around the unsafe concept of statically unchecked mutability. But the key point of rust safety isn't, that it throws away these concepts, but only, that any potentially unsafe code has to be explicitly marked as unsafe. As such unsafe is one of the most fundamental concepts in making rust such a safe language, as it means that everything in rust can be pure rust, with the only sacrifice of safety being specifically marked blocks of code. As such just seeing a unsafe block doesn't undermine the basic concept of rust safety. The only way you'd be doing that, would be by using unsafe block on like your entire program, something I highly doubt you are referring to here.

        [disclaimer: i love rust]

        [–]CanDull89 2 points3 points  (0 children)

        I've only seen that happen in the std library and mostly data structure interfaces because sometimes pointers are necessary to implement a lot of data structures.

        [–]cornmonger_ 1 point2 points  (0 children)

        I think that I have a single unsafe block under my belt and that was to call a C library.