Stop Memsetting Structures
31–40 of 277 posts
Re: Stop Memsetting Structures
#32Another 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.
This expression is false in any C99 compliant system:
Section 6.3.2.3 [0]:
> An integer constant expression with the value 0, or such an expression cast to type void * , is called a null pointer constant. [1] If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function
> Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.
The technicality of the memset example is that it does not set the bits of the pointer by referring to it as a pointer, so the requirement that 0 behave as if it was a null pointer does not apply.
[0] http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
[1] In text footnote: The macro NULL is defined in (and other headers) as a null pointer constant; see 7.17
EDIT: Formatting
Re: Stop Memsetting Structures
#33Because of c spec idiocy it isn’t event sufficient to use memset anymore, you need to use memset_s. But “stop memsetting” is clearly nonsense if you care about security.
Re: Stop Memsetting Structures
#34It 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 memset() and works in C89 too.
And finally, there is absolutely no reason to check if a pointer is NULL just before calling free() on it
This is advice I agree with. The nullcheck is in free() itself (IMHO a good design decision --- especially along error-handling and cleanup paths.)
Re: Stop Memsetting Structures
#35Earlier 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
#36This is mostly a matter of taste, but if the first example makes sense, the second example looks less clear, because, for someone quickly skimming through the code, a variable which have a somewhat clear meaning "yes" (that could be improved) is replaced with a magic number who have no intrinsic meaning.
Re: Stop Memsetting Structures
#37Am 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)); ?
What are we saying 'yes' to?
Re: Stop Memsetting Structures
#38 &(int) {1}
is equivalent to int one = 1;
&one
How did I not know about this? I'll be using it from now on.Re: Stop Memsetting Structures
#39Earlier quoted context omitted.
Sending structures that include padding or that you don’t know the exact layout of over the network is another thing you shouldn’t do, period. Code doing that may break with a compiler change or a compilation flag change on one end of the connection, even if you can guarantee both ends use the same CPU.
> Sending structures that include padding or that you don’t know the exact layout of over the network is another thing you shouldn’t do, period. What if you do know the exact layout and it happens to have a gap between fields?
Re: Stop Memsetting Structures
#40That'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 - GCC, Clang and MSVC all happen to make it zero, but it's not guaranteed by the C language.
The trick with avoiding a variable when passing an address to a literal value is nice though, I didn't know that. There are some places in my code that could use it ;)