Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>https://crates.io/crates/bitflags

Not native, see C.

>Rust's raw pointers have equivalent power to C's pointers.

Again, AFAIK you can't do type punning.

That wasn't even my point, that was that C gives you almost everything a cpu does and not much more.



> Not native.

Bitflags crate is native; 100% Rust, 0% C. Here is the source: https://github.com/rust-lang-nursery/bitflags/blob/master/sr...



I am sorry, but really I don't understand specifically which difference between C bitfields and Rust bitflags you regard as crucial. Is it about the feature being baked into the compiler vs. available as an external macro package? But the only reason it needs to be baked into the compiler in C is because there's no other choice - the C preprocessor syntax is too limited and awful.


I believe the point is that C bitfields allow sub-word addressing; the variable refers to specific bits within a word. The Rust flags is the same as using bitwise operations on word-sized values.

To be honest, I don't know if a functional difference, but I have not done any embedded programming where there might be a difference.


Accessing bitfields in C just ends up compiling to bitwise operations on word-sized values anyway.


I've seen plenty of hardware registers that use one bit for some X, two bits for some Y, and 5 bits for some Z. (Yes, in embedded programming.) One way of dealing with that is with C bitfields.

Now, I never did it that way myself. I just and-ed it with a bitmask to get the part that I wanted. But it's a bit messier to do it that way, because if you want one of the fields as a number, and it's not from the least-significant bits, then you have to shift it as well as mask it, whereas with bitfields you can just read it as a number and get the right value.


Spend a few minutes writing wrapper functions and its done.

Never bothered me on Turbo Pascal days, plus if I remember correctly bitfield ordering is not portable across compilers anyway.


What does "native" mean, built into the language? Why does it matter?

I suspect it's the same with type punning (though also, to some degree because we're still working out the details of what exactly the semantics of unsafe are.) In the end, you can always cast stuff to bytes and then cast those bytes to something else.

I don't take (too much) objection to that, and little with "not much more", but that doesn't mean that C has some secret stuff that only C can do, which it feels like you're implying.


>What does "native" mean, built into the language? Why does it matter?

I don't know how that macro works, but in kernel C bitfields are used in structs that map to device registers (that are mapped to memory).

>I suspect it's the same with type punning (though also, to some degree because we're still working out the details of what exactly the semantics of unsafe are.) In the end, you can always cast stuff to bytes and then cast those bytes to something else.

So if i want to store a series of things with random (length) types in a single array, i can ? Sounds like i can, even though you explained the simpler case.

>I don't take (too much) objection to that, and little with "not much more", but that doesn't mean that C has some secret stuff that only C can do, which it feels like you're implying.

And for the third (edit:second) time, that is not my point. Thing is that C does not have "secret stuff" and rust does. In C you get what you wrote, and not much more. There is no need for telling the compiler to not do some checking or to not make a copy of something. (edit2: granted, bitfields are not native to cpus as type punning is)

Rust, IMO, is more for the C++ crowd then C. And those two are very different.


In C you get what you wrote, and not much more

This is really not the case, not with modern C compilers. You may find calls to functions from the standard library to be converted in surprising ways, while touching undefined behaviour can eliminate evaluations, branches, function calls and more. Your mental model might have a close resemblance to assembly; but compilers don't see it like that any more.


>You may find calls to functions from the standard library to be converted in surprising ways, while touching undefined behavior can eliminate evaluations, branches, function calls and more.

Yes, things like memcpy and printf are (in most cases) built-in in compilers. Not surprising really.

Undefined behavioral is bad programming, if your ask me. Almost all examples of it, that i ran across, are in really ugly code that only a "smart" programmer would write.

Clangs static analyzer points out undefined behavior, and gcc is close to getting a "-Wundefined" flag that points that out at compile time.

A optimizing C compiler can change the resulting code even more then just doing dead code elimination. But the point still stands, that C maps well to assembly and that languages that do things like their own memory allocation are not even comparable to what the cpu provides (only automatic memory allocation that a cpu somewhat provides is the stack, and C exposes even that).


Deterministically locating all undefined behavior is undecidable. Static analyzers can only locate a subset of it.

Commonly-used type punning techniques frequently exhibit undefined behavior due to strict aliasing: https://blog.regehr.org/archives/1307 .


"Deterministically locating all undefined behavior is undecidable. Static analyzers can only locate a subset of it."

It might be true but barely matters when we have tools like KCC. It's built on an executable semantics of C that runs in a framework on top of Maude rewrite engine.

http://www.kframework.org/index.php/Main_Page

https://github.com/kframework/c-semantics

http://fsl.cs.illinois.edu/FSL/papers/2015/hathhorn-ellison-...


That's fascinating; thank you for that. I often find academic papers are too densely written to me to read, but the authors of that paper have gone out of their way to describe everything in a straightforward manner.


> I don't know how that macro works, but in kernel C bitfields are used in structs that map to device registers (that are mapped to memory).

Same thing. There's no requirement to use it in a kernel context, though you can if you'd like.

> So if i want to store a series of things with random (length) types in a single array, i can ? Sounds like i can, even though you explained the simpler case.

Yes, though it'd use a lot of unsafe code.

> And for the third (edit:second) time, that is not my point. Thing is that C does not have "secret stuff" and rust does.

Ah, sorry! The contrapositive (or whatever) is tough. My bad for misunderstanding.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: