1

On the line where it has malloc(sizeof(Item) I get an error of:

a value of type void* cannot be used to initialize an entity of type Item*

Code item->color = _color; gives me a similar error:

const char* cannot be assigned to an entity of type char*

Moreover, on the compareIdLowHigh function const Item** for both pfirst and psecond give me

const void* cannot be used to initialize entity of type const Item**

I don't know how to fix these errors.

Reference code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 7

typedef struct {
    int id;
    double price;
    char* color;
} Item;

Item* initItem(int _id, double _price, const char* _color)
{
    Item* item = malloc(sizeof(Item));
    item->id = _id;
    item->price = _price;
    item->color = _color;
}

void printItem(Item* item)
{
    printf("Id: %d\t\tPrice: %f\t\tColor: %s\n", item->id, item->price,
        item->color);
}

void printItems(Item* items[], size_t size)
{
    for (int i = 0; i < size; ++i)
        printItem(items[i]);
    printf("\n");
}

int compareIdLowHigh(const void* a, const void* b)
{
    const Item** pfirst = a;
    const Item** psecond = b;
    const Item* first = *pfirst;
    const Item* second = *psecond;
    if (first->id < second->id) return -1;
    else if (second->id < first->id) return 1;
    else return 0;
}

int comparePriceHighLow(const void* a, const void* b)
{
    // TODO
}

int compareColorAlpha(const void* a, const void* b)
{
    // TODO
}

int main()
{
    // initialize items
    const size_t COUNT = LENGTH;
    Item* itemPtrs[LENGTH];
    itemPtrs[0] = initItem(0, 12.12, "red");
    itemPtrs[1] = initItem(11, 14.14, "blue");
    itemPtrs[2] = initItem(32, 1.67, "black");
    itemPtrs[3] = initItem(13, 5.54, "brown");
    itemPtrs[4] = initItem(54, 17.20, "purple");
    itemPtrs[5] = initItem(15, 20.24, "yellow");
    itemPtrs[6] = initItem(6, 99.99, "orange");
    printItems(itemPtrs, COUNT);
    // sorting items
    printf("sorting items by id (lowest to highest):\n");
    // TODO
    printItems(itemPtrs, COUNT);
    printf("sorting items by price (highest to lowest):\n");
    // TODO
    printItems(itemPtrs, COUNT);
    printf("sorting items by color (a-z):\n");
    // TODO
    printItems(itemPtrs, COUNT);
    // cleanup items
    for (int i = 0; i < 7; ++i)
        free(itemPtrs[i]);
}
Egel
  • 1,796
  • 2
  • 24
  • 35
Brandizzy
  • 21
  • 2
  • malloc returns a `void*` so you just need an explicit cast back to the required type: `Item* item = (Item*)malloc(sizeof(Item));`. – monkey0506 May 27 '18 at 22:21
  • 5
    @monkey0506 [no, you don't, not if your C compiler is standard-compliant](https://stackoverflow.com/a/605858/1322972). – WhozCraig May 27 '18 at 22:22
  • 4
    @monkey0506 only if you are in C++. Maybe you think you are coding in C, but Visual Studio by default is C++ – unalignedmemoryaccess May 27 '18 at 22:22
  • Are you compiling this as C++ or C code? Your question title said C, which is why I removed the C++ tag. –  May 27 '18 at 22:22
  • Compiling in C. – Brandizzy May 27 '18 at 22:29
  • 5
    How do you know you're compiling in C? Try temporarily adding `int class = 42;` at the very top of your source file. If your compiler complains about that, then it's a C++ compiler (`class` is a keyword in C++ but not in C). – Keith Thompson May 27 '18 at 22:43
  • It sounds like it's still using the C++ compiler. In Visual Studio, right click on the source file in the Solution Explorer, select Properties, then under C/C++ > Advanced, change the "Compile As" option to "C". Now you just need to change the `color` type to `const char*`, or modify your code to allocate and copy the string data if you're using non-literal strings. – paddy May 28 '18 at 00:39
  • `const Item** pfirst = a;` is an error (`const` cannot be removed from a level without a cast) . It should be `const Item* const * pfirst` – M.M May 28 '18 at 01:22
  • Side note: avoid identifiers beginning with underscore. These might collide with identifiers inside the standard libraries. – Lundin May 28 '18 at 09:22
  • In fact the error message "a value of type `void*` cannot be used to initialize an entity of type `Item*`" is a strong clue that you're using a C++ compiler, but `int class = 42;` makes the point more clearly. – Keith Thompson May 28 '18 at 21:03

1 Answers1

4

a value of type void* cannot be used to initialize an entity of type Item*

The malloc code is fine. You either get this warning because VS is non-conforming compiler, or because you are compiling the code as C++. If the problem persists after setting VS to compile in C mode, get a better compiler.

const char* cannot be assigned to an entity of type char*

Pretty self-explaining. Either you allow the pointer to be changed and then drop const correctness in const char* _color. Or you don't allow the pointer to be changed, then make the struct member const char* color;.

const void* cannot be used to initialize entity of type const Item**

const Item** is a pointer-to-pointer to const Item. This is a different pointer type than const void* since they have different qualifiers. You can probably solve the compiler error with something obscure such as const Item*const* pfirst, but that isn't the actual root of the problem.

I take it you are writing a function to pass to bsearch/qsort etc, and what you have is an array of pointers. In which case you should only convert a and b to const Item*. I'm not sure why you bring in the Item** in the first place.

Lundin
  • 195,001
  • 40
  • 254
  • 396