3 ms·
You're probably not serious, but why waste time and complexity copying structure elements into a buffer (which likely needs to be memset/bzero'd!), if you can j
by anyfoo 8y ago
You're probably not serious, but why waste time and complexity copying structure elements into a buffer (which likely needs to be memset/bzero'd!), if you can just directly use the struct, all consistent with the standard?
C is not a very high-level language. Apart from where undefined behavior is called out, you can and should assume how data is represented on a low level. It was made for writing operating systems and their kernels after all, where interfacing in a bit-accurate way is common.
- bjourne 8y agoI'm joking because endless flame wars have already been spent debating this issue. But I realize not everyone has heard them yet, so let's strap on the football shoes and bring out the horse carcass one more time! There are platforms on which NULL, integer 0 and floating point 0 is not the same. Hence memsetting won't do the right thing. On modern platforms they are, but still, you don't want to get the Standard C Weenies on your back - they're even more annoying than the Rust Evangelism Strike Force. You don't want demons coming out of your nose, do you? :) They do have a point, though. Suppose you are handling a struct you thought were memsetted but was not (your stupid team mate used those damn initializers!), then when serializing it you will get undefined bytes in the stream, possibly triggering hash values to mismatch causing mysterious rebuilds and other stuff. Wrt to field accesses, yes those can overwrite padding bytes. Suppose a is an 8 bit char field, but padded to 4 bytes. Then "foo->a = 22" could be translated to "MOV [RSP+16], EAX" which overwrites the 3 padding bytes with undefined values. The solution, as you mention, is to use packed structs but in those field accesses are much less efficient. Bottom line: code whichever way you want. :) Me, I like to live in the fast lane from time to time and those memset/cpy/cmp functions are sooo handy. :)
- andrewshadura 8y agoBy the standard, the null pointer must be equivalent to 0.
- yuubi 8y agoOnly if you use conversion within the language: void *p=0; If you said memset(&p, 0, sizeof(p)) then that's not guaranteed to work on all implementations.
- uryga 8y agogizmo686's comment [1] explains the subtle difference: > [...] 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. [1] https://news.ycombinator.com/item?id=19767316 https://news.ycombinator.com/item?id=19767316
- deleted 8y ago[deleted]
- nybble41 8y agoThe memory representation of the null pointer is implementation-defined. The C99 standard only guarantees that a integer constant expression with the value 0, implicitly or explicitly cast to a pointer type, will give a null pointer. It does not guarantee that a null pointer cast to an integer type (other than _Bool) will give the value 0; all pointer-to-integer casts are implementation-defined. It also does not guarantee that a non-constant expression which evaluates to 0 will produce a null pointer if cast to a pointer type. In short, there may exist counter-intuitive but nonetheless standards-compliant platforms where tests such as "assert((uintptr_t)(void * )0 == 0);" or "int x = 0; assert((void * )x == (void * )0);" would fail.