Does that also zero the padding that may exist between elements of the structure (or at its end)? Because if not, not memset'ing will open you up to all kinds of info leaks, especially if you plan to send that struct over the network (or to another process, or from kernel to userspace...). EDIT: Actually I have to apologize, because I’m not certain what the C standard says about whether the padding bytes can change w…
Stop Memsetting Structures
41–50 of 277 posts
Re: Stop Memsetting Structures
#42Earlier quoted context omitted.
Nope it doesn't: //GCC: -O0 //MSVC: /Od #include #include struct S { unsigned char x; int y; }; int f(int f) { S a; memset(&a, f, sizeof(a)); unsigned char y[2]; memcpy(&y, &a, sizeof(y)); return y[1]; } int g() { S a = { 1, 2 }; unsigned char y[2]; memcpy(&y, &a, sizeof(y)); return y[1]; } int main(int argc, char *argv[]) { f(0xDD); printf("%#x\n", g()); f(0xFF); printf("%#x\n", g()); } It definitely seems like the…
That doesn’t check whether that memset call writes 0xFF bytes in the padding. The compiler could also determine that &a.x)[1] is undefined behavior in C (reading past the end of an object), and take advantage of that. The way to check that is by disassembling the code, and even that doesn’t say what a C compiler should do, only what these particular compilers do.
Re: Stop Memsetting Structures
#43Another reason to not memset structures: In the code struct foo { void * bar; } baz; ... memset(&baz, 0, sizeof(struct foo)); assert(baz.bar == NULL); it's possible for the assertion to fail, since NULL it not guaranteed to be represented in memory by a zero bytes.
> it's possible for the assertion to fail, since NULL it not guaranteed to be represented in memory by a zero bytes. Technically correct (which is of course the best kind of correct) but you'd be hard pressed to find a system in 2019 where NULL != (void*)0. The most recent machines with non-zero NULL in the C FAQ entry on the matter ( http://c-faq.com/null/machexamp.html ) date back to the mid '90s.
NULL == (void*)0.
But given void *p = 0;
intptr_t i = 0;
it is not guaranteed that `memcmp(&i, &p, sizeof(p)) == 0`.Re: Stop Memsetting Structures
#44Am I the only one who finds this int yes=1; setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes)) ; much cleaner than this setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int)); ?
The author of that code is trying to make it explicit -- "yes, I want to allow reuse of local addressses". Some will prefer this, some won't.
I personally like the use of the variable, though I think it's not worth getting all bent out of shape about it one way or another. But I guess we all have our pet peeves, and I know I'm guilty of getting all bent out of shape about things that ultimately don't matter much.
Re: Stop Memsetting Structures
#45Does that also zero the padding that may exist between elements of the structure (or at its end)? Because if not, not memset'ing will open you up to all kinds of info leaks, especially if you plan to send that struct over the network (or to another process, or from kernel to userspace...). EDIT: Actually I have to apologize, because I’m not certain what the C standard says about whether the padding bytes can change w…
Nope it doesn't: //GCC: -O0 //MSVC: /Od #include #include struct S { unsigned char x; int y; }; int f(int f) { S a; memset(&a, f, sizeof(a)); unsigned char y[2]; memcpy(&y, &a, sizeof(y)); return y[1]; } int g() { S a = { 1, 2 }; unsigned char y[2]; memcpy(&y, &a, sizeof(y)); return y[1]; } int main(int argc, char *argv[]) { f(0xDD); printf("%#x\n", g()); f(0xFF); printf("%#x\n", g()); } It definitely seems like the…
But yeah, I should have mentioned the caveats too. I will update the post once I'm back at my computer.
Re: Stop Memsetting Structures
#46Re: Stop Memsetting Structures
#47Does that also zero the padding that may exist between elements of the structure (or at its end)? Because if not, not memset'ing will open you up to all kinds of info leaks, especially if you plan to send that struct over the network (or to another process, or from kernel to userspace...). EDIT: Actually I have to apologize, because I’m not certain what the C standard says about whether the padding bytes can change w…
Please explain how you send a struct over the network without UB and leaking the padding.
Re: Stop Memsetting Structures
#48Earlier quoted context omitted.
Nope it doesn't: //GCC: -O0 //MSVC: /Od #include #include struct S { unsigned char x; int y; }; int f(int f) { S a; memset(&a, f, sizeof(a)); unsigned char y[2]; memcpy(&y, &a, sizeof(y)); return y[1]; } int g() { S a = { 1, 2 }; unsigned char y[2]; memcpy(&y, &a, sizeof(y)); return y[1]; } int main(int argc, char *argv[]) { f(0xDD); printf("%#x\n", g()); f(0xFF); printf("%#x\n", g()); } It definitely seems like the…
I am aware of the fact that unitilized padding can have nasty side effects: https://lwn.net/Articles/417989/ But yeah, I should have mentioned the caveats too. I will update the post once I'm back at my computer.
Re: Stop Memsetting Structures
#49Another reason to not memset structures: In the code struct foo { void * bar; } baz; ... memset(&baz, 0, sizeof(struct foo)); assert(baz.bar == NULL); it's possible for the assertion to fail, since NULL it not guaranteed to be represented in memory by a zero bytes.
struct S {size_t a, void *p;};
foo = (struct S) {0};
Does the standard require the compiler to set any pointers to NULL, or will everything be implicitly zeroed leaving pointers possibly improperly initialized to NULL?Re: Stop Memsetting Structures
#50Am I the only one who finds this int yes=1; setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes)) ; much cleaner than this setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int)); ?
I agree anything is better than a magic number, but really only if the variable is properly descriptive. What are we saying 'yes' to?