error: invalid use of void expression

CodeBlocks...
warning: dereferencing 'void *' pointer [enabled by default]|
error: invalid use of void expression

I believe i do not know how to properly use the generic void* pointer. I want to pass data to pointer to void so that to be able to manipulate any type of data the user wants to use. The functions below is just a test to show my intentions.
I am using only c language syntax. I do not want c++ syntax for these.

I have asked a very similar question in the past but i did not quite get it. It was not the kind of response i was hoping for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int foo(void* x, void* y)
{
    *x  = 3;
    *y = *x + 1;
    return 0;
}

void* foo1( void* x)
{ *x = *x +1; }
 
int main(void)
{
    int a=7;
    int b = 5;
    char c = 'a';
    foo(&a,&b);
    printf("%d\n%d\n",a,b);

    foo1(&c);
    printf("%c\n",c);
    
}
e]
In function 'int foo(void*, void*)':
5:6: error: 'void*' is not a pointer-to-object type
6:6: error: 'void*' is not a pointer-to-object type
6:11: error: 'void*' is not a pointer-to-object type
In function 'void* foo1(void*)':
11:4: error: 'void*' is not a pointer-to-object type
11:9: error: 'void*' is not a pointer-to-object type
11:15: warning: no return statement in function returning non-void [-Wreturn-type]


Normally when using void pointers, one has to cast the pointer to a type.

http://stackoverflow.com/questions/16986214/why-type-cast-a-void-pointer#16986872
When doing some kind of operation on data the compiler needs to know the type, otherwise it doesn't know what machine code to generate. For example, addition between two signed 32-bit integers uses a different CPU instruction than addition between two unsigned 16-bit integers, or between two floating point numbers. Addition between two class types requires that the correct overload of operator+ is called, but if the compiler doesn't know the types there is no way it could know which overload to call.

If you can use C++ features you might find function templates useful. The compiler will then be able to automatically generate code (at compile time) for each type that you pass to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

template <typename T>
int foo(T* x, T* y)
{
    *x  = 3;
    *y = *x + 1;
    return 0;
}

template <typename T>
T* foo1(T* x)
{
    *x = *x +1;
    return x;
}
 
int main(void)
{
    int a=7;
    int b = 5;
    char c = 'a';
    foo(&a,&b); // calls foo<int>
    printf("%d\n%d\n",a,b);

    foo1(&c); // calls foo1<char>
    printf("%c\n",c);
}
Last edited on
Cast your pointer to the desired type before manipulating it.

The problem with foo() is that there are non-enforceable requirements on the real type of the pointed-to object. You either need to know the type is (i.e., by passing it in as a macro parameter or via a printf-style specifier), or you need to make assumptions about the type based on its size, and you'd have to pass the size in.

The real solution is to not use void* here. Generic programming in C is awful.

Is something like this what you're thinking of?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* Some way to signal the real type of an argument.  Such a type is analogous to
   printf's format string -- that's one way to signal type too. */
/* User-defined structures will need to be handled through a proxy function */
typedef enum TypeLabel { Char_T, SChar_T, UChar_T, Int_T, UInt_T, /* ... */ } TypeLabel;
void increment(TypeLabel c, void* x) {
# if ! defined BRANCH
# define BRANCH(label, type) do {                      \
    /* Manipulate x here */                            \
    case label: *((type*)x) = (*(type*)x) + 1; return; \
  } while(0)

  switch (c) {
    BRANCH(Char_T , char);
    BRANCH(SChar_T, signed char);
    BRANCH(UChar_T, unsigned char);
    BRANCH(Int_T  , int);
    BRANCH(UInt_T , unsigned int);
    /* ... */
  }
# else
# error "BRANCH already defined"
# endif 
}

# include <stdio.h>
int main(void) {
  int bar = 3;
  increment(Int_T, &bar);
  printf("%d\n", bar);
}


http://coliru.stacked-crooked.com/a/5c5f42258e8f2c92
Last edited on
Topic archived. No new replies allowed.