Live data from Hacker News

Stop Memsetting Structures

anmolsarma.in

181–190 of 277 posts

Re: Stop Memsetting Structures

#181
post #68
post #41

Earlier quoted context omitted.

Please explain how you send a struct over the network without UB and leaking the padding.

Use a packed struct (e.g. __attribute__((packed))). You may take a performance hit due to lack of alignment, but that's the judgement call

__attribute__((packed)) is not part of the standard, and therefore doesn't quite answer the question. I believe the standards-compliant way of doing this is that "you can't".

Re: Stop Memsetting Structures

#182

Earlier quoted context omitted.

Why? memset followed by memcpy must return the same byte everywhere. Otherwise what would memset even mean?

I feel like accessing the bytes that correspond to padding might be implementation-defined, but I couldn't find this in the standard.

I don't think it is. It wouldn't make sense since memcpy is basically supposed to convert between arbitrary binary data.

Re: Stop Memsetting Structures

#183
post #68

Earlier quoted context omitted.

Use a packed struct (e.g. __attribute__((packed))). You may take a performance hit due to lack of alignment, but that's the judgement call

Would this work struct S {char data, char pad0, char pad1, char pad2}; int main() {S dataStruct; printf("%s", dataStruct.data); return 0;} and give me a 4-byte struct or would the compiler optimize it all away and leave me with a 1-byte struct?

Since you don't actually access the size of the structure, I see no reason why it matters. Also, FWIW, your code has undefined behavior because you call printf with the wrong type.

Re: Stop Memsetting Structures

#184

Earlier quoted context omitted.

Why would it be to spite everyone? Big endian is network order by definition. It's hard-coded into every asic in switches and routers for decades. If you don't use big endian your packets won't even make it to where you want. Of course, your own payload can do whatever you want as long as you know with 100% certainty nobody else will ever want to talk to your application and get confused.

Consider the lorawan spec which was written in the last 5 years. The stack is designed to be implemented in software on small 32 bit microcontrollers which are _all_ little endian. And it's big endians. The people that wrote that spec knew that and went with big endian anyways. Also I work with people that do network hardware. They can't care less about little or big endian. Makes no difference to them.

Someone needs to pick one or the other: you can't have it both ways.

Re: Stop Memsetting Structures

#185

Earlier quoted context omitted.

I feel like accessing the bytes that correspond to padding might be implementation-defined, but I couldn't find this in the standard.

I don't think it is. It wouldn't make sense since memcpy is basically supposed to convert between arbitrary binary data.

From a practical point of view, yes, but I would be very surprised if the C standard had any accommodation for memcpy being a way to leak the value of a structure's padding.

Re: Stop Memsetting Structures

#186
post #91

I disagree with this author on both counts. 1. Zero filling is theoretically unnecessary, yes. But theory is not often reality. Zero filling is a defensive measure that protects you from other code that makes unhealthy assumptions. Code external to yours may make assumptions about what lies in your padding, either by doing memcmp's, or adding new fields in a later version of the struct and intending it to be ABI comp…

The compiler may elide memset if it's not possible to access the value in a standards-defined way, so your defense might not actually be doing anything.

Re: Stop Memsetting Structures

#187
post #170
post #5

Earlier quoted context omitted.

Same. But also, I feel like most of The Force's efforts are directed at C++. I could be wrong.

That makes no sense - C++ eliminates many of the memsafety concerns that are problematic in C

It also occasionally obfuscates some of the safety issues under the guise of "smart" classes.

Re: Stop Memsetting Structures

#188

Earlier quoted context omitted.

Yes. If you look at the commit history you'll find that we've fixed a few of them already.

Yeah, I saw the comment and big block of bulls in bad tar. Here's two from memory: parent pointer in tree_entry, although it seems unused anyway. buff pointer in the link hash thing. (My bad, I looked at it on my laptop, which is not here anymore. I can drop an email later.)

Used to read your blog several years ago, and really enjoyed it. Good seeing your name pop up again.

Re: Stop Memsetting Structures

#189
post #110
post #100

Earlier quoted context omitted.

I've only written a little of each, but my impression is that C has mostly remained a focused, effective language for careful systems programming. While C++ has become a sprawling cthulhu of leaky abstractions and other nasty foot-guns and people only use it because "it's as fast as C but sorta feels like a higher-level language". And that therefore Rust is a strict improvement over C++, but not necessarily C.

I thought this way too until I worked with competent C++ devs on a modern code base. (By my definition of “competent,” no one ever encountered by the Rust brigade bloggers is competent, fwiw). At some point, I realized that C++ is a language for implementing new languages in a way that is backward compatible with existing programs. Templates are Turing complete (lazily evaluated, purely functional, and side-effect fr…

> Templates are Turing complete (lazily evaluated, purely functional, and side-effect free), so whatever your language of choice can do can be backported to C++ (granted, painfully, but probably less painfully than throwing out all your legacy code and starting from scratch).

This does not logically follow, since templates are evaluated at compile time and hence have restrictions on what they can do.

> C++ supports zero-cost abstraction, so it will get very close to low level C performance (including constant propagation, loop unrolling, type-unsafe transformations, hoisting, inlining, etc, etc) even if you throw piles of lambdas and encapsulated methods at it.

You do have to be careful with what you're doing, though.

> the compiler is slooooowww

I mean, it's not like the Rust compiler is fast either…

Re: Stop Memsetting Structures

#190
post #116

Because it’s 2019! It really irritates me when people give arguments like this. I seriously don't care what year it is, I care that the code I write works. A lot of projects still use C89 because they want the widest portability. C99 isn't very new, but especially in the embedded and other niche industries, C89 (often with some extensions) is all you get. That said, "= { 0 };" is almost always usable instead of a mem…

Actually, I had some code that passed null to free(), and it segfaulted on some old version of Red Hat. (Not RHEL, Red Hat.)

That's either your platform's problem, in which case you should be very worried, or (more likely) you had some other undefined behavior somewhere else and it ended up biting you inside free.
Post reply on HN