1

For school I have to write an agenda, it has to hold data about exams, tasks and lectures

I'm having trouble accessing an enum in my struct.

My struct looks as follows:

struct Item{

enum {TASK, EXAM, LECTURE} entryType;

char* name;
char* course;

time_t start;
time_t end;

union
{
    struct Task* task;
    struct Exam* exam;
    struct Lecture* lecture;
} typeData;
};

Now I have to set the type of the item using my enum. This struct is defined in Item.h. In Item.c which includes Item.h I use the following code:

struct Item* createItem(char* type){
struct Item* newItem;

newItem = (struct Item *) malloc (sizeof(struct Item));

if (strcmp(type, "Task") == 0)
{
    //newItem->entryType = newItem->TASK;
    newItem->typeData.task = createTask();
} else if (strcmp(type, "Exam") == 0)
{
    //newItem->entryType = newItem->EXAM;
    newItem->typeData.exam = createExam();
} else if (strcmp(type, "Lecture") == 0)
{
    //newItem->entryType = newItem->LECTURE;
    newItem->typeData.lecture = createLecture();
}

return newItem;
}

The commented code gives me the error (for TASK for example):

error C2039: 'TASK' : is not a member of 'Item'

crognar
  • 65
  • 1
  • 7
  • `TASK` is not `task`. –  Aug 03 '13 at 14:46
  • What are you doing all the string comparison for? If you are using an enum, there is no reason for `strcmp`. Enum members work just like integers. – Cody Gray - on strike Aug 03 '13 at 14:47
  • 1
    Also, [don't cast the return value of `malloc()`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). –  Aug 03 '13 at 14:47
  • The string comparison is because i get the type from user input, so I use strings to determine which item has to be created. The comparison part of the code works as I intend it to work, I just can't access newItem->TASK to set the type of the newly created item. – crognar Aug 03 '13 at 14:52
  • @H2CO3 We were thaught to cast the return type of malloc(), I have read in numerous places it's not needed but we are required to do so (don't ask me why) – crognar Aug 03 '13 at 14:54
  • @crognar I'm not asking, I'm telling :) So that's because your lecturer happens to have absolutely no knowledge of fundamental good C programming practices, that's why. If you read the reasoning (the answer I've linked to), I hope you will stop doing this when you are free to write whatever you want. –  Aug 03 '13 at 14:55
  • 1
    He probably thinks he's teaching C++. He's not, C and C++ are two different languages. You never cast in C, and you never use C-style casts in C++. – Cody Gray - on strike Aug 03 '13 at 14:58
  • There is NOTHING wrong with casting the value returned from malloc. In fact, you might need to do so when using a compiler that performs a lot of type checking. – JackCColeman Aug 03 '13 at 19:27
  • @JackCColeman No, not in C. `void *` is implicitly convertible to and form any object pointer type. **Everything** is wrong with casting it. –  Aug 04 '13 at 08:55
  • @CodyGray I wasn't aware that you couldn't cast in C... – MarcusJ Dec 26 '14 at 17:54

2 Answers2

3

When you declare an enum, its contents essentially become compile time constants as if you had #defined them. In particular, if you have an enum { A, B, C } foo, you access the options by A, not foo->A as you seem to think.

Kevin
  • 53,822
  • 15
  • 101
  • 132
  • So how do you access enum Name1 { Value2 = 0x1;}? like the code I'm using needs to be able to pick the value name from 0x1, not Value2; like you would in a class – MarcusJ Dec 26 '14 at 17:57
2

My first point is unnecessary, secondly change the parameter of createItem to an int, thirdly your using pointers in dataType so we really should see those functions, fourthly create a field of int in your struct called type.

   struct Item* createItem(int type){
   struct Item* newItem;

   newItem = malloc (sizeof(struct Item));    

  newItem->entryType = type;

   if (type == 0)
   {
     newItem->typeData.task = createTask();
   } else if (type == 1) 
   {
     newItem->typeData.exam = createExam();
   } else if (type == 2)
   {
     newItem->typeData.lecture = createLecture();
   }

 return newItem;
 }
Joe Tyman
  • 1,417
  • 5
  • 28
  • 57
  • Thanks for the tip about using ints for the type, I'll see to that. And the typeData functions don't give me any errors, they work so I don't see a reason to give the code for them. But the problem is in our assignment we already got the Item struct, and I copied it exactly. Is there no way to do it without making the enum global? – crognar Aug 03 '13 at 15:08
  • @crognar you can use int to access the value of enum. So any int and entryType are interchangeable. – Joe Tyman Aug 03 '13 at 15:10
  • @crognar the code I have up now doesn't require a global enum. – Joe Tyman Aug 03 '13 at 15:13
  • Thank you very much, this solved my problem. I guess you can't really access the different values which are defined inside the struct by using the names? – crognar Aug 03 '13 at 15:22
  • @crognar For simplicity yes, you can't just point to an enum value. If the enum was global your main would have knowledge of the enum value and send one along. Since it doesn't and you as the programmer know what is in the enum you can just pass along an int(assuming you did proper error checking) to the struct. – Joe Tyman Aug 03 '13 at 15:34