-2

I have the following structure:

struct Some_Struct {
    uint32_t a;
    int16_t  b;
    uint8_t  c;
};

struct Other_Struct {
    uint32_t a;
    uint32_t b;
    uint32_t c;
};

The variable size is being calculated as such:

uint32_t size = sizeof(Some_Struct) + sizeof(Other_Struct) * n;

My question is, given a sizeof Some_Struct and Other_Struct whose actual size is dependent on the platform, architecture, and packing, how can I at runtime determine the maximum number of n allowed before size rolls over?

Zhro
  • 2,546
  • 2
  • 29
  • 39
  • 3
    "as specifying [0] is undefined." - That's not quite exactly correct. Use a _flexible array member_: `Other_Struct e[]`. That `[1]` hack is legacy and invokes undefined behaviour in modern C. – too honest for this site Sep 08 '16 at 20:03
  • This is only supported by C99. C++ which is tagged also does not support flexible array members. – Zhro Sep 08 '16 at 20:05
  • 3
    With the above notes i guess its time to ask the question yet again, is this `c` or `c++`? They are not the same language and will not have the same answer. – Fantastic Mr Fox Sep 08 '16 at 20:06
  • Well, C standard is C11, nothing else. And whoever uses ancient C should move on; it's 17 years obsolete now. About C++: That's a different language and you should not use such constructs in C++ at all! Please restrict your question to **one** language. C and C++ are **not** compatible! – too honest for this site Sep 08 '16 at 20:07
  • 1
    Updated the question as it concerns C++. I am working on a legacy codebase which used `[0]` everywhere. In an effort to cleanup compiler warnings I've adjusted them to `[1]` and have been correcting declarations accordingly. This question relates to some code I found along the way. – Zhro Sep 08 '16 at 20:09
  • Another note: sending a raw `struct` over a network (or marshalling it directly in general) is a very bad idea. It does not account for padding, endianess, etc. – too honest for this site Sep 08 '16 at 20:09
  • You are correct but I'm not addressing this issue at the present time. My question is very specifically regarding calculating the valid range for `n`. – Zhro Sep 08 '16 at 20:10
  • My comment above implies the valid range: the valid range for `n` is exactly `1 ... 1`. Well, you can allocate more, but just must not access anything else than `.e[0]` with your approach. – too honest for this site Sep 08 '16 at 20:12
  • The question has been updated. – Zhro Sep 08 '16 at 20:17
  • Unclear about the validity of `uint32_t size = sizeof(Some_Struct) + sizeof(Other_Struct) * n;` should alignment requirements affect things. Posting the application of `size` would add value and clarity to the post. – chux - Reinstate Monica Sep 08 '16 at 20:40
  • Any changes to the maximum limit due to alignment is not being considered as the current implementation has a laundry list of problems. This is just a patch which adds logging of a rollover where it was previously being cast and truncated. One impossible task at a time. – Zhro Sep 08 '16 at 20:53

1 Answers1

0

You can use numeric_limits:

uint32_t maximum_n = (std::numeric_limits<uint32_t>::max() - sizeof(Some_Struct))
                                / sizeof(Other_Struct);
villapx
  • 1,743
  • 1
  • 15
  • 31