3

How do I check if my structure has a member something in C99?

#include <stdlib.h>
#include <string.h>

struct some {
  char title[50];
  char name[50];
};

int main() {
  struct some s;

  if (*s.something) { // Error: no member named 'something' in 'struct.some'
    strcpy(s.something, "Hello");
  }
}

UPDATED:

I don't need to know if it exists at compile time, but in a built program. The members and their values will be parsed from a file and then consumed to the struct in a loop but I need to be sure that it will skip all non-existing members.

artnikpro
  • 5,487
  • 4
  • 38
  • 40
  • 9
    This would not compile, so this is how you would know. If you wanted to implement structures which can have members added or removed at runtime, it's a much more complex topic. – Daniel Kamil Kozar Jan 30 '17 at 20:22
  • @DanielKamilKozar No, I don't need a struct that can have members added or removed. I just need to check if a member exists, and give it a value if so. – artnikpro Jan 30 '17 at 20:35

3 Answers3

6

C99 (or even C++) does not support reflection. So there is no way of checking if a struct contains a member with a particular name at runtime; the compiler will tell you at compile time instead.

This is different from other languages, like, for example, java, which support reflection.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • C supports [generic selection](https://stackoverflow.com/a/28897994/975097), so it is possible to check the type of a struct at compile-time. – Anderson Green Aug 30 '21 at 12:26
3

When you read the file in question, you should know what each field is. Since you know at compile time which ones you're interested, the code will only look for those fields.

Taking your sample struct containing a name and a title, suppose you have a file like this:

name:myname1,title:mytitle1,year:2016
name:myname2,title:mytitle2,year:2017

When you read each row, you'll find that each row contains fields named name, title, and year. Since the struct in your code only knows about name and title, it would populate just those fields and should ignore the rest.

Here's some pseudo-code to illustrate:

void processline(char *line, struct some *data) {
    char key[50];
    char value[50];
    while (getnextpair(line,key,value)) {
        if (!strcmp(key, "name") {
            strcpy(data->name, value);
        } else if (!strcmp(key, "title") {
            strcpy(data->title, value);
        } else {
            printf("unknown field %s\n", key);
        }
    }
}
dbush
  • 205,898
  • 23
  • 218
  • 273
3

You could add a type field to all structs that might be checked. Add an enumeration to represent the types and use a method that takes a struct pointer, a type from the enumeration, and a method that returns a bool. Then you could make something that's functionally equivalent and very close to what you tried to code.

Mikeologist
  • 438
  • 4
  • 11