0

enter image description here

How can there be idCount of idEntries if idEntries is an array of only 1 element? Wouldn't this only be true if it was so: idEntries[idCount]?

Brackets
  • 464
  • 7
  • 12
  • Where is this from? – Trevor Hickey Nov 20 '16 at 16:45
  • 3
    This is an instance of the 'Struct Hack' at work (see [C struct hack at work](http://stackoverflow.com/questions/16553542/c-struct-hack-at-work) for one of no doubt many possible references). It isn't good practice in Modern C — the flexible array member (FAM) was added to C99 to support it directly in the language. Technically, C++ doesn't support the FAM concept. I'm not sure it supports the struct hack either. Code using the technique is usually treading on thin ice, therefore. No, you can't have a variable size array in a structure, so the `idEntries[idCount]` notation is a non-starter. – Jonathan Leffler Nov 20 '16 at 16:45
  • @JonathanLeffler So is it a bad practice?I haven't seen this kind of hack anywhere else. – theVoid Nov 20 '16 at 16:49
  • 1
    One problem in C++ is that you cannot use the `new` mechanisms to allocate the structure — you're forced to use `malloc()` and friends to do the memory allocation. The intent is that you allocate `sizeof(ICONDIR) + idCount * sizeof(ICONDIRENTRY)` bytes in total, and treat the first `sizeof(ICONDIR)` bytes as the `ICONDIR` structure, and the array happens to extend into the extra space added. That's not good C++ style, needless to say. – Jonathan Leffler Nov 20 '16 at 16:49
  • Yes, it is bad practice. You may be forced to use it because of compatibility reasons, but you should not code like that yourself. It could be a `vector idEntries`, for example, and then you don't need the separate count. – Jonathan Leffler Nov 20 '16 at 16:50
  • @JonathanLeffler Indeed, it might be a bad practice in general. But it is hard to avoid if you do some Win API stuff. (And MS allows [unsized arrays](https://msdn.microsoft.com/en-us/library/b6fae073.aspx).). – AlexD Nov 20 '16 at 16:53
  • @AlexD: Interesting — what Microsoft refers to as an 'unsized array' is what the C99 and C11 standards refer to as a 'flexible array member' or FAM. And I noted that 'compatibility reasons' might be why you need to use it — compatibility with Win API calls may be a reason to use it. It doesn't alter the observation that you should not design your code using that technique unless external constraints demand it. (I note that G++ does allow FAMs; the C++ standard does not.) – Jonathan Leffler Nov 20 '16 at 16:56
  • @TrevorHickey https://msdn.microsoft.com/en-us/library/ms997538.aspx – Brackets Nov 20 '16 at 17:00
  • @JonathanLeffler Why can't I use `new` to allocate structure? I have seen people using it, I have been using it and it works. – Brackets Nov 20 '16 at 17:02
  • @Brackets I assume because you cant allocate the extra memory for the buffer with new. – theVoid Nov 20 '16 at 17:05
  • So how many `idEntries` are there created? Does it become like `vector`'s `push_back` every time I write to next array's element? – Brackets Nov 20 '16 at 17:13
  • 1
    FAM breaks the contract laid out by the `struct` by taking advantage of the extra space asked for when the structure was `malloc`ed. Unless you go with placement `new` into a presized allocation, `new` will build a `ICONDIR` with exactly one `ICONDIRENTRY` as per the contract. – user4581301 Nov 20 '16 at 17:17
  • @Brackets There are no `push_back`s, memory gets allocated just once. The point is to have a continuous chunk: "the header" and then the array. – AlexD Nov 20 '16 at 17:17
  • Is it how many additional `sizeof(ICONDIRENTRY)`s I allocate with `malloc`? – Brackets Nov 20 '16 at 17:18
  • That's a yes.21 – user4581301 Nov 20 '16 at 17:19

0 Answers0