4 ms·
It's just not guaranteed to 0 out y Citation needed. As far as I'm aware, memsetting structs is perfectly fine. The problem are things like memcmp as padding b
by cygx 7y ago
It's just not guaranteed to 0 out y
Citation needed. As far as I'm aware, memsetting structs is perfectly fine. The problem are things like memcmp as padding bytes take unspecified value.
- aw1621107 7y agoI believe y may not be zeroed out if there is padding between x and y. Now, whether any actual compiler would insert padding there, I have no idea.
- Gibbon1 7y agoI do memory twiddling a lot in C. The answer is what happens in practice depends on the machine alignment. On an 8 bit machine generally alignment is 1 byte and there is no padding. On a 32 bit machine yeah you'll have 3 bytes of padding for each element. Me I think alignment is increasingly a bad idea. Most modern processors don't deal with memory in word sized chunks anymore. Padding just increases cache pressure. Either way the example is trashfire grade C.
- tumult 7y agoThat is not how padding and alignment works in C. The example above has no padding between each field, because the implementation specifies how much padding there should be. For clang, gcc, and msvc, on x86 and AMD64, there is no padding between chars in a struct. if the struct were instead { char a; int b; } then there would be 3 bytes of padding between a and b. The example is not trashfire and is in fact totally valid. Common ARM processors will fault if you try to perform an unaligned access. You must align where required. Edit: correction to mistake above: I originally wrote { int a; char b; } and should have said the padding came after b. I've fixed it to match the explanation text and have the padding between. I should really be writing these posts in a separate text editor.
- Const-me 7y ago> if the struct were instead { int a; char b; } then there would be 3 bytes of padding between a and b. I doubt it. To get 3 bytes of padding between fields, you need this: { char a; int b; }
- tumult 7y agoYes! Sorry, my mistake. int then char on x86 will put the padding at the end of the struct, not in the middle. I had originally written it that other way (char and then int), then edited it to be the other way (int and then char) but didn't update the other text. I edited the post to have this correction.
- bluGill 7y agoFor x86 and XMD64. What about arm, Mips, Sparc, alpha, whatever what in the IBM mainframes... All of the above have C compilers and each does something different. I don't know the rules for each, but I know some of them have really weird rules in specific cases.
- tumult 7y agoWhat? Why don't you look it up? Why are you asking here, when you can find each of these with a few seconds of searching or downloading manuals?
- bluGill 7y agoYou misunderstand. In context of the grandparent: all the world is NOT x86/AMD64. there are many other processes with many different rules. That his code works on the above two doesn't mean it will on the others.
- tumult 7y agoI took care to mention that x86 is not the only platform, and to what extent they're relevant. I also made sure to not specifically answer as if this is only for x86. I don't know why you're willingly misinterpreting what I said. It's quite frustrating, especially after I took care to not answer as if x86 were the only platform. I asked you why you're asking about specifics here in a querying conversational, when you can just search the internet and be given the specific answers immediately. Because you're asking me to reply again, I'll go ahead and answer your question for you: all of those platforms are the same as far as padding/alignment for char is concerned. But just to reiterate, I was careful to not require this kind of knowledge for my replies to make sense.
- barrkel 7y agoFields are generally aligned so that they are at an offset which is an integer multiple of the field type's alignment. Type alignment for built-in types is generally the highest power of two which is both (less than or equal to the type's size) and (less than or equal to the maximum alignment for the target ABI). Type alignment for compound types (like struct) is generally the maximum of the constituent types' alignments. But details may vary from implementation to implementation and platform to platform.
- DagAgren 7y ago> Most modern processors don't deal with memory in word sized chunks anymore ARM does. That is a very modern processor in very wide use. Linux hides this from you by trapping illegal memory accesses and handling them in software. Instead of a crash, you get abysmal performance if you do not align correctly.
- cygx 7y agoAnd I believe that's wrong. Memset copies values to bytes, regardless if they are padding or not. You just can't rely on padding bytes keeping that value. In particular, writing to a member may fill padding with arbitrary garbage (though the standard goes beyond that, ie you shouldn't rely on padding values ever).
- aw1621107 7y agoWhy would it be wrong? If there's 3 bytes of padding between x and y, then writing 2 bytes of 0s to &a would zero out x and the first padding byte, but would not zero y.
- cygx 7y agoYeah, my bad. I missed the point of the example (ie that the size argument might be too small). I assumed the point was memset writing to padding bytes. It is indeed true that y might not get zeroed in principle (though I doubt that'll happen in practice for this particular example as padding gets introduced to maintain alignment, and alignment factors a type's size, which is 1 in case of char). A better example would be struct boxed_value { uint16_t flags; double value; }; struct boxed_value v; memset(&v, 0, sizeof (uint16_t) + sizeof (double)); That's of course a braindead way to write it instead of the more convenient memset(&v, 0, sizeof v); That said, neither case will invoke undefined behaviour.
- aw1621107 7y agoI'm mildly surprised that wouldn't invoke undefined behavior if there was padding between the fields of the struct due to writing over only part of the second field, but then again I'm not as intimately familiar with the C standard as I should be.
- cygx 7y agoBytewise access is always possible and won't violate the strict aliasing/effective typing rules. The worst that could happen when messing with IEEE floating point values that way is creating a signalling NaN (if they are available).
- deleted 7y ago[deleted]