22

i have the following structure

typedef struct 
{
   char      data1[10];
   char      data2[10];
   AnotherStruct  stData;
}MyData;

for some reason the implementors choose not to make the stData as pointer, so i have to live with that. my problem is how do i check if the stData member is empty? because if it is empty i need to skip certain things in my code.

any help is appreciated

user2101801
  • 719
  • 2
  • 8
  • 20
  • 2
    In general you can't. But `AnotherStruct` could have a field called `empty`, and you could check that. – juanchopanza Sep 18 '14 at 05:45
  • 3
    Null-ness only applies to pointers. I'm afraid you are making assumptions about C++ that stem from a Java or maybe even C# background, but you will have to unlearn those. BTW: C and C++ are different languages, too, so answers to one generally don't apply to the other, although this case is an exception. – Ulrich Eckhardt Sep 18 '14 at 05:47
  • That will depend on the case. It is not a pointer so it cannot be "null". It can be zerofilled but it doen't mean it is empty either, it only means its filled with zeros. I believe there is some property of `AnotherStruct` that you use to check it's validity, theres just no way to tell you what it is without knowing how this struct is supposed to be used. – Havenard Sep 18 '14 at 05:48
  • If and only if zero filled struct means empty, you can use ´memcmp´ but as other commentors suggested, there should be a method to check if the struct is valid/not empty. – bkausbk Sep 18 '14 at 05:57
  • you need to specify how the struct should look like when it is "empty" - a struct in C/C++ is never empty, it is just filled with with something more or less well-defined and it is up to you or the one who designed it to determine the interpretation. – AndersK Sep 18 '14 at 06:53

7 Answers7

16

You need some way to mark AnotherStruct stData empty.

  • First check (or double-check) the documentation and comments related to AnotherStruct, possibly ask those who made it if they are available, to find out if there is an official way to do what you want.

  • Perhaps that struct has a pointer, and if it is null pointer, the struct is empty. Or perhaps there is an integer field where 0 or -1 or something can mean empty. Or even a boolean field to mark it empty.

  • If there aren't any of the above, perhaps you can add such a field, or such an interpretation of some field.

  • If above fails, add a boolean field to MyData to tell if stData is empty.

  • You can also interpret some values (like, empty string? Full of 0xFF byte?) of data1 and/or data2 meaning empty stData.

  • If you can't modify or reinterpret contents of either struct, then you could put empty and non-empty items in different containers (array, list, whatever you have). If MyData items are allocated from heap one-by-one, then this is essentially same as having a free list.

  • Variation of above, if you have empty and non-empty items all mixed up in one container, then you could have another container with pointers or indexes to the the non-empty items (or to the empty items, or whatever fits your need). This has the extra complication, that you need to keep two containers in sync, which may or may not be trivial.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • I disagree. Either the implementors have already defined a way to mark `stData` as empty, then use that way and that way only. Or it is not meant to be empty, then don't try to reinterpret its semantics. – Arne Mertz Sep 18 '14 at 08:14
  • 1
    @ArneMertz I don't see how your comment disagrees with my answer. The question of OP does not make sense if there isn't some "empty" state, or need for such a state. First bullet covers it being already built in, two last bullets cover the case of empty struct in itself not making sense, ie. there being just used and unused entries. – hyde Sep 18 '14 at 08:28
  • 1
    @ArneMertz And in addition to implementors having already defined a way, or implementors meant that it can not be empty, there are also the options that implementers didn't think of it, the requirements have changed, or the implementors just didn't know what they were doing... – hyde Sep 18 '14 at 08:30
  • it disagrees because your list reads like "try around until you find something that works for you" as compared to "read the docs and mark it empty the way it's meant to be done". wrt the implementors not having thought of the empty state: if they didn't, then the functions taking the struct as parameters won't expect an empty state, so dont use it that way. If requirements change, then the implementors have to change the library and define a way to mark it empty, or the OP has to write a wrapper. Implementors not knowing what they are doing means not using the struct at all. – Arne Mertz Sep 18 '14 at 09:59
  • 1
    @ArneMertz I agree about the documentation, added to the answer as new first bullet. But the rest... real world does not work like that, unfortunately. Being able to just throw out for example some library, or some legacy module, and do it from scratch, is a luxury that is not always available. – hyde Sep 18 '14 at 10:12
  • therefore my advice to write a wrapper/adapter or other compatibility support for the class. Just don't fiddle around with third party stuff if it is not meant to be used that way. – Arne Mertz Sep 18 '14 at 10:27
  • 1
    @ArneMertz As I understand it, the question is about how to write the code that would go *into* the wrapper/adapter. – hyde Sep 18 '14 at 10:39
4

I find myself in a similar fix as you (did). I am required to packetize a given structure and knowing the exact number of bytes in the structure would help me serialize the structure. However, some structures are empty and hence, serialization fails to align exact number of bytes.

Although this is 3 years later, I found the following solution that worked for me:

template <typename T> struct is_empty {
    struct _checker: public T { uint8_t dummy; };
    static bool const value = sizeof(_checker) == sizeof(T);
};

The result can be be queried as is_empty<T>::value and is available at compile time.

template <typename S>
typedef union {
    struct __attribute__((__packed__)) {
        ObjId   id;
        S       obj;
    } dataStruct;
    std::array<uint8_t, (sizeof(dataStruct) - is_empty<S>::value)> byteArray;
} _msg_t;

Here are the references:

Community
  • 1
  • 1
3

you can find some flag variable. ex.

struct AnotherStruct {
    bool valid;
    char aother_data1[10];
    char aother_data1[10];
    //...
};

if (stData.valid==true){
    //do something
}
thomas
  • 505
  • 3
  • 12
1

if it not a pointer then memory for structure member will be allocated when object MyData is created.When you define your structures set them all to zero with calloc or memset, then later you can compare to 0

Rajath N R
  • 41
  • 2
0

Struct is user-defined type as int is built in type.

struct x;
int y;

First try to answer "How can you determine if your int is empty OR not after first declaring it"

Regarding solution:- Use your struct this way if you want to know whether its initialized OR not:-

struct X
{
  bool b;
  X() : b(false) {}  
};

set it true when initialized.

ravi
  • 10,994
  • 1
  • 18
  • 36
  • this is C++ regarding solution isn't it? If so, you should state it, otherwise: tell me since when bool is common for c. (Not _Bool) – dhein Sep 18 '14 at 07:13
0

I assume the struct definition is part of some third party functionality/library, where the third party may well be someone inside your own company.

If the implementors chose to not make stData a pointer, then there are reasons. They will have an idea about how to express "stData is empty", if it is even allowed to be empty. You should definitely try to look up those semantics in the documentation or talk to them. Don't try to add your own semantics to a structure that has a specific purpose and semantics.

So if there is a predefined way to express that part of the struct is empty, use that way. If it may not be empty for the uses it is intended for, then don't try to make it empty. In a nutshell, don't use a class/struct in a way it is not meant to be used. Instead, if you find yourself in a situation where you only have part of the data that is needed for the 'MyData' to make sense, then write your own 'MyPartialData' struct to deal with that situation and translate it to a 'MyData' once you have everything needed and are ready to interact with the third party API.

Arne Mertz
  • 24,171
  • 3
  • 51
  • 90
0

In my case I had to detect if it was NULL masquerading as a struct. This worked for me:

bool IsThisNull(PayloadParamBase& p)
{
    if (&p == nullptr)
        return true;

    return false;
}

Nullity was detected by the address of the struct being nullptr.

UserX
  • 485
  • 5
  • 12