Live data from Hacker News

Comparative unsafety

flak.tedunangst.com

21–30 of 99 posts

Re: Comparative unsafety

#21
post #15
post #11

Earlier quoted context omitted.

Extra maddening, as it works fine with Javascript disabled. Those loading and rendering progress bars are a terrible idea.

It's a joke. It's not a terrible idea. It's a great idea! A great joke!

Well, aside from the delay in seeing the content, it borks the back button up, etc. Breaking all the pages on your site for a joke is an odd idea to me.

Edit: As mentioned by another commenter, seems to be deliberate punishment for having javascript enabled. Also, clicking outside the main window (like in the url bar) does the render thing again. And a search for javascript has some odd results too: https://flak.tedunangst.com/search?q=javascript Last, there's some deliberately awful infinite scrolling too.

Re: Comparative unsafety

#22
post #19

This has the most toxic UI I've seen in my life. Switching away from my browser and back again causes the page to re-render, losing my place as it did so. Just awful!

I'm pretty sure it's explicitly intended solely as punishment for people who have javascript enabled.

Fwiw I think it's pretty hilarious.

Also I warmly recommend to view-source, the makeprogress() function is a true delight.

Re: Comparative unsafety

#23

> I wrote some rust code. Actually, he wrote some Rust and some C code wrapped in Rust. > I was writing an smtp server... the kind of smtp server you'd write in two days. (sigh) > The error would have been detected far sooner had I not been lazy and checked the return value of chown (for a file not found error). But [excused here] You can't, and mustn't avoid C error checking when writing C code, even if it's wrapped…

> I was a TA in a first-semester course in C programming for several years, and one of the harder things to inculcate is how return value checking is not optional. It's very tempting to assume your standard library function just works, always.

The situation is worse than that. People check for errors except when they don't. And you are expected to know the difference. Take for instance malloc. It can return NULL but you don't check for it, because that's just the way it's done. Or take close(2).

> If close() is interrupted by a signal that is to be caught, it shall return -1 with errno set to EINTR and the state of fildes is unspecified.

> This permits the behavior that occurs on Linux and many other implementations, where, as with other errors that may be reported by close(), the file descriptor is guaranteed to be closed. However, it also permits another possibility: that the implementation returns an EINTR error and keeps the file descriptor open. (According to its documentation, HP-UX's close() does this.) The caller must then once more use close() to close the file descriptor, to avoid file descriptor leaks. This divergence in implementation behaviors provides a difficult hurdle for portable applications, since on many implementations, close() must not be called again after an EINTR error, and on at least one, close() must be called again.

How did this discrepancy go unnoticed for so long? Because no one checks close return value. Everyone nods and say you should, and then keep writing code without checks, because come one close never fails. If you do check you are the weird edge case. The one people whisper about "why does he have to be such an annoying pedant".

And while I'm ranting, the same goes for undefined behavior. Of course you shouldn't rely on undefined behavior. Of course of course. But maybe, just a little pointer casting is fine?

Re: Comparative unsafety

#24
post #12

Wait, what? I don't know rust, at all, but why is path freed? I thought rust didn't have GC? > let path = CString::new(filename.as_str()).unwrap().as_ptr(); Is one of those functions calling free behind the scenes?

I mean, yeah, at the end you only get a raw pointer, the object managing the pointer doesn't exist anymore. I'm not a Rust programmer, but I would imagine it's equivalent to the following C++ code

    auto ptr = std::string(something).c_str();
This creates a std::string, calls c_str() on it to get the pointer. However, since the std::string isn't stored anywhere, its lifetime stops and it is destructed (this is why these are called temporaries), and the pointer is now invalid. The right way of doing it is this:

   std::string str { something };
   auto ptr = str.c_str();
Now, str and ptr both live in the same scope, and ptr's lifetime is entirely contained in str's.

Re: Comparative unsafety

#25
post #12

Wait, what? I don't know rust, at all, but why is path freed? I thought rust didn't have GC? > let path = CString::new(filename.as_str()).unwrap().as_ptr(); Is one of those functions calling free behind the scenes?

like C++, rust frees values once they've gone out of scope; the result of

    CString::new(filename.as_str()).unwrap()
is a temporary which is freed at the end of that line, since the .as_ptr() returns a non-lifetime-encumbered value.

Re: Comparative unsafety

#26

> Why am I using my own ffi version of chown instead of the libc crate? The libc crate prototypes chown with unsigned uid_t and gid_t types, and I want to pass -1 because I'm not interested in changing the group. I'll spare you the long rant about how one should never redeclare system interfaces if you can't take the time to do so properly, because it turns out if you dig into it, uid_t boils down to uint32_t , but e…

Yes, !0 would work. Or, to make the intent even more clear:

    -1_i32 as u32
Definitely better than declaring your own function prototype.

Re: Comparative unsafety

#27

From my perspective as someone who knows Rust but primarily works with high-level languages like JavaScript, some developers who from a background of unsafe languages (particularly C and C++) seem incredibly cavalier around `unsafe` blocks in Rust code. It's like they're desensitised to the unsafety. As someone who is used to working in a language where one absolutely cannot hit memory safety issues or undefined beha…

Maybe that's all true, but in the specific example in question, he just does a string conversion and calls into a C library via ffi (for a reason he has justified). I think he has a real point about how the compiler should find this error if Rust is to fully match its marketing, so to speak. Clippy (a tool for style issues as much as anything else) doesn't seem to be an appropriate place for such error checking.

On balance Rust does a great job, but "be even more careful in unsafe Rust than in regular C++" is probably a losing battle.

Re: Comparative unsafety

#29

This has the most toxic UI I've seen in my life. Switching away from my browser and back again causes the page to re-render, losing my place as it did so. Just awful!

Looking at the source, the progress bar is completely fake, it really does nothing besides making you wait. It even introduces slight delays to make it look more realistic.

Why? Just why? The worst part is that the site is actually very light, with none of the ads, analytics and resource hog frameworks that are all too common these days. It probably could load almost instantly if it wasn't for that fake progress bar.

Edit: Judging by the other comments, it looks like it is some kind of political statement against Javascript. I disagree with such practices but well, that's his site, his choice.

Re: Comparative unsafety

#30

> Why am I using my own ffi version of chown instead of the libc crate? The libc crate prototypes chown with unsigned uid_t and gid_t types, and I want to pass -1 because I'm not interested in changing the group. I'll spare you the long rant about how one should never redeclare system interfaces if you can't take the time to do so properly, because it turns out if you dig into it, uid_t boils down to uint32_t , but e…

In Rust the simplest way would be to use the `u32::MAX` constant. Create a fun alias for it if you want to express intent.
Post reply on HN