4

This produces an incompatibility warning:

#include <stdlib.h>
#include <stdio.h>

typedef struct
{
  int key;
  int data;
  struct htData_* next;
  struct htData_* prev;
}htData_;

typedef struct
{
  int num_entries;
  struct htData_** entries;
}ht_;

ht_* new_ht(int num_entries);
int ht_add(ht_* ht_p, int key, int data);

int main()
{
  int num_entries = 20;
  //crate a hash table and corresponding reference                                                                                                              
  ht_* ht_p = new_ht(num_entries);
  //add data to the hash table                                                                                                                                  
  int key = 1305;
  ht_add(ht_p,key%num_entries,20);

  return 0;
}

ht_* new_ht(int num_entries)
{
  ht_ *ht_p;
  ht_ ht;
  ht.num_entries = num_entries;
  ht_p = &ht;

  //create an array of htData                                                                                                                                   
  htData_ *htDataArray;
  htDataArray = (htData_*) malloc(num_entries * sizeof(htData_));
  //point to the pointer that points to the first element in the array                                                                                          
  ht.entries = &htDataArray; // WARNING HERE!!!!!!!!!!!!!!!!

  return ht_p;
}

I'm trying to copy the **ptr to the struct containing a **ptr.

Update: My simplified code was not accurate so I've posted the actual code.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
nick_name
  • 1,353
  • 3
  • 24
  • 39
  • 2
    Also mention that which line is producing warning – iammilind Jul 26 '11 at 04:12
  • what is `htData_ array[20] = htDataArray;` intended to do? – Mark Elliot Jul 26 '11 at 04:12
  • I've added a better and easier to understand test failure case replacing specifically that line. Thanks for looking and I apologize for the lack of organization... – nick_name Jul 26 '11 at 04:14
  • 2
    You only need to make the cast on malloc if you are in C++. In plain C it is usually recomended to skip the cast (it is verbose and more error prone) – hugomg Jul 26 '11 at 04:15

2 Answers2

4

The problem is that struct htData_ and htData_ are not the same thing! As far as the compiler is concerned, struct htData_ doesn't exist—it's an incomplete type. htData_, on the other hand, is a typedef for an anonymous structure. For a more detailed analysis, see Difference between struct and typedef struct in C++.

So, you're getting a warning because ht.entries is declared as the type struct htData_**, but the right-hand side of that assignment has type <anonymous struct>**. To fix this, you need to define struct htData_:

typedef struct htData_
{
    ...
} htData_;
Community
  • 1
  • 1
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
1

This line is not proper:

htData_ array[20] = htDataArray;

You cannot assign a pointer to an array.

In your edited code, here is the problematic line:

//point to the pointer that points to the first element in the array                                                                                          
  ht.entries = &htDataArray;

Actually, syntactically it's correct, so it should not give warning. But you are doing wrong stuff here. If you want ht.entries pointing to the first element of array than you need to declare it as,

htData_* entries;  // 'struct' keyword not needed ahead of declaration

and assign it as,

ht.entries = &htDataArray[0];
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • How about with the updated replacement of that line? I still get the error yet it makes sense to assign a ** to a ** of the same type. – nick_name Jul 26 '11 at 04:15
  • The warning is still produced if ht.entries = &htDataArray; is replaced by ht.entries = &htDataArray[0];. Did I misunderstand your comment? Also, I'm not trying to just have ht.entries point to the first element in the array. I want a pointer that points to a pointer pointing to the first element in the array. More simply, htDataArray points to element 0 in the array. I want to point to htDataArray, which is a **. – nick_name Jul 26 '11 at 04:24
  • @nick_name, did you change the declaration to `htData_* entries;` ? – iammilind Jul 26 '11 at 04:25
  • I could do that, but that wouldn't accomplish what I'm going for. I want a pointer to a pointer to the first element in the array. – nick_name Jul 26 '11 at 04:29
  • But current code will not help you getting the pointer to the first element too. First element of the array is of type `htData_` and pointer to that will be `htData_*`. So you have to change the declaration of `entries`. – iammilind Jul 26 '11 at 04:32