Live data from Hacker News

Stop Memsetting Structures

anmolsarma.in

81–90 of 277 posts

Re: Stop Memsetting Structures

#81

Earlier quoted context omitted.

Tbh I'm not a network person, but my naive brain says instead of casting to char* and writing to the buffer, couldn't you just write out individual fields to a buffer so you control every byte? That seems smarter and safer.

Do you write a separate serialization function for every single struct and sub-struct you send over a network? And then continue maintaining every single one to keep it consistent whenever a field is added/removed/modified in any struct? (Though I should mention that macros actually do make this doable, but they're hardly pretty, and I have yet to see many people embrace this approach, if they realize it's possible a…

> Do you write a separate serialization function for every single struct and sub-struct you send over a network? And then continue maintaining every single one to keep it consistent whenever a field is added/removed/modified in any struct?

Yes? Of course you do that? Or pick one of a hundred libraries that do that for you - protobuf, cap'n proto, flatbuffers, etc...

Re: Stop Memsetting Structures

#82

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…

Damn straight! That's why I exclusively use punch cards, for that good ol' reliability. Don't need no new fangled language crap! Sugar is for eating, not for syntax!

If you're actually stuck with C89 you have my sympathy, like all the people stuck still maintaining FORTRAN and COBOL. But that's obviously a niche case with extreme limitations, it doesn't really need to be brought up every time someone mentions C99. Or C++11 for that matter.

Re: Stop Memsetting Structures

#83
post #63
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.

Rust is a big language, like C++. It feels too complicated compared to C.

It's not about size, it's about predictability and explicitness. Rust has features, though it also won't do anything you don't tell it to do, and its guarantees hold throughout. You don't have to know and understand how something works to be effective, just the languages guarantees. All the abstractions have zero cost anyways. If you want to write "like C but with guarantees" that's totally fine, and you can safely and predictably interface with anyone elses libraries.

tl;dr: while big, it reduces your cognitive load through strong guarantees. Think of it more as progressive disclosure of complexity.

Re: Stop Memsetting Structures

#84

> Elements that are not specified are initialized as if they are static objects: arithmetic types are initialized to 0; pointers are initialized to NULL. That's actually not true. It is the case when initializing arrays, but for structs (and unions) any non-named member has "indeterminate value" (see paragraph 9, section 6.7.8 of ISO/IEC 9899:1999; unchanged in C11 and C18). Well, at least according to the standard -…

C11 6.7.9.19 says "all subobjects [of an object initialized with a initializer list] that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration."

Re: Stop Memsetting Structures

#85
The memsetting code is more obvious for older programmers and probably more compatible too. I don't want to start a flame or something, but if you want shiny new programming features and initialisation you should probably look away from C and try javascript ot something similar. One of the reasons we love C is that the same code compiles and works cleanly on the latest linux, a freebsd 4.11. or PIC16.

Re: Stop Memsetting Structures

#86
post #77
post #75

Earlier quoted context omitted.

Nope, memset will often be “optimized” such that padding is not zeroed. It’s not because the compiler sees that padding isn’t observed, it’s because reading from padding is undefined. Because reading from padding is undefined the write (also undefined) by definition has no observable side effects. Memset_s is the only way to guarantee that padding is actually zeroed, well memset or bzero_s obviously. It’s critically…

Right, but zeroing padding only matters for security reasons. If your memset isn't being done for security reasons, then memset() is better than memset_s().

If you are processing data from the network, any uninitialized read gets attacked. My experience is padding (both inside a struct, and outside - array alignment for instance) gets attacked.

The only safe option is to initialize everything.

I say this having spent more than a decade working on software that is always being attacked.

Re: Stop Memsetting Structures

#87

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…

Damn straight! That's why I exclusively use punch cards, for that good ol' reliability. Don't need no new fangled language crap! Sugar is for eating, not for syntax! If you're actually stuck with C89 you have my sympathy, like all the people stuck still maintaining FORTRAN and COBOL. But that's obviously a niche case with extreme limitations, it doesn't really need to be brought up every time someone mentions C99. Or…

COBOL and Fortran are indeed still wide used, however I claim there is way more C89 than those two together. The point about C89 is that this covers a large area - all common Unix/Linux APIs and libraries are at least C89 compatible, if not written using C8 and as the GP mentioned embedded often depends heavily on such compilers. Thus usage goes far across industries with new libraries being created each day. COBOL and Fortan are way more in their fields (legacy business and science respectively) where more and more logic is build around those old systems using newer languages.

Re: Stop Memsetting Structures

#88

> Elements that are not specified are initialized as if they are static objects: arithmetic types are initialized to 0; pointers are initialized to NULL. That's actually not true. It is the case when initializing arrays, but for structs (and unions) any non-named member has "indeterminate value" (see paragraph 9, section 6.7.8 of ISO/IEC 9899:1999; unchanged in C11 and C18). Well, at least according to the standard -…

Para 9 is talking about members that do not have names in the struct definition. Missing initializers are covered later:

21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

Re: Stop Memsetting Structures

#89

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…

#include

struct abc { int a; int b; int c; };

int main() {

  struct abc b = {2};
  printf("a b c = %d %d %d\n ", b.a, b.b, b.c);
  return 0;
}

% c99 test.c

% a.out

a b c = 2 0 0

Re: Stop Memsetting Structures

#90

Earlier quoted context omitted.

Do you write a separate serialization function for every single struct and sub-struct you send over a network? And then continue maintaining every single one to keep it consistent whenever a field is added/removed/modified in any struct? (Though I should mention that macros actually do make this doable, but they're hardly pretty, and I have yet to see many people embrace this approach, if they realize it's possible a…

> Do you write a separate serialization function for every single struct and sub-struct you send over a network? And then continue maintaining every single one to keep it consistent whenever a field is added/removed/modified in any struct? Yes? Of course you do that? Or pick one of a hundred libraries that do that for you - protobuf, cap'n proto, flatbuffers, etc...

That's the protobuf approach, but things like Capnp are different, right? Isn't its wire format its in-memory format? I thought it was closer to the "straight memcpy" approach.

Protobuf serialization functions can turn into a lot of generated code too (read: big binaries) and stomp all over your icache, because they're different for each type. More "data-driven" approaches using type-generic functions with some runtime type-specific data (like proto descriptors&reflection) can be a good tradeoff for code that isn't as "hot". Typically more branchy than a memcpy or a type-specific function though.

Post reply on HN