“'void*' is not a pointer-to-object type”

2019-06-21 13:17发布

I have a problem in my code. In Xcode or using the C++11 compiler, this code works well. However, when I am submitting this code to an Online Judge, the verdict shows "Compile Error". I think they use the C++4.7.1 compiler, which when I tried to compile it (using Ideone), it says:

prog.cpp: In function 'void printArray(int)':
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type
prog.cpp:27: error: 'void*' is not a pointer-to-object type

This makes no sense because there are no void*'s anywhere in this program.

I don't have any inkling what to change though. It would be great if you guys help me to solve this. Below is my code:

#include <iostream>
#include <math.h>
#include <cmath>
#include <tgmath.h>

int array[10] = {1,2,3,4,5,6,7,8,9};
int initial = 1;
int tmp;
int total[500];

using namespace std;

void swap(int x, int y){
    int temp = array[x];
    array[x]=array[y];
    array[y]=temp;

    return;
}

void printArray(int size){

    int i;
    for (i=0;i<size;i++){
        //cout<<array[i]<<" ";
        tmp= array[i];
        tmp= (tmp* (pow(10.0,(size-i-1))));  // <--- Error here
        total[initial]=total[initial]+ tmp;
    }
    initial++;
    tmp=0;
    //cout<<endl;
}

void permute(int k,int size){
    int i;
    if (k==0) printArray(size);
    else{
        for (i=k-1;i>=0;i--){
            swap(i,k-1);
            permute(k-1,size);
            swap(i,k-1);
        }
    }

    return;
}

void quickSort(int arr[], int left, int right) {
    int i = left, j = right;
    int tmp;
    int pivot = arr[(left + right) / 2];

    while (i <= j) {
        while (arr[i] < pivot)
            i++;
        while (arr[j] > pivot)
            j--;
        if (i <= j) {
            tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
            i++;
            j--;
        }
    };

    if (left < j)
        quickSort(arr, left, j);
    if (i < right)
        quickSort(arr, i, right);
}

int main(){
    int countertest;
    cin>>countertest;
    int ak, asize;

    for(int a= 0; a<countertest; a++){

        initial = 1;
        std::fill(total, total+500, 0);
        cin>>asize>>ak;
        permute(asize,asize);

        quickSort(total, 1, initial-1);

        int arraydex [10000], temp = total[ak];
        for(int z = asize; z>=0; z--){
            arraydex[z] = temp % 10;
            temp /= 10;
        }

        for(int bc = 1; bc<=asize; bc++){
            cout<<arraydex[bc]<<" ";
        }
        cout<<endl;
    }

    return 0;
}

2条回答
孤傲高冷的网名
2楼-- · 2019-06-21 13:27

The issue here is a conflict between <tgmath.h> and <cmath> / <math.h>.

Here's what I've found when opening up the source file to <tgmath.h> on my Linux system:

#define pow(Val1, Val2) __TGMATH_BINARY_REAL_IMAG (Val1, Val2, pow, cpow)

This is important - it's redefining pow to use this other macro. This is immediately a problem, because it's #define-ing away the normal pow function.

So what does this function do? Well, let's look at __TGMATH_BINARY_REAL_IMAG:

# define __TGMATH_BINARY_REAL_IMAG(Val1, Val2, Fct, Cfct) \
 (__extension__ (((sizeof (__real__ (Val1)) > sizeof (double)       \
       || sizeof (__real__ (Val2)) > sizeof (double))       \
      && __builtin_classify_type (__real__ (Val1)       \
          + __real__ (Val2)) == 8)    \
     ? ((sizeof (__real__ (Val1)) == sizeof (Val1)        \
   && sizeof (__real__ (Val2)) == sizeof (Val2))        \
  ? (__typeof ((__tgmath_real_type (Val1)) 0        \
       + (__tgmath_real_type (Val2)) 0))        \
    __tgml(Fct) (Val1, Val2)            \
  : (__typeof ((__tgmath_real_type (Val1)) 0        \
       + (__tgmath_real_type (Val2)) 0))        \
    __tgml(Cfct) (Val1, Val2))            \
     : (sizeof (__real__ (Val1)) == sizeof (double)       \
  || sizeof (__real__ (Val2)) == sizeof (double)        \
  || __builtin_classify_type (__real__ (Val1)) != 8     \
  || __builtin_classify_type (__real__ (Val2)) != 8)    \
     ? ((sizeof (__real__ (Val1)) == sizeof (Val1)        \
   && sizeof (__real__ (Val2)) == sizeof (Val2))        \
  ? (__typeof ((__tgmath_real_type (Val1)) 0        \
       + (__tgmath_real_type (Val2)) 0))        \
    Fct (Val1, Val2)              \
  : (__typeof ((__tgmath_real_type (Val1)) 0        \
       + (__tgmath_real_type (Val2)) 0))        \
    Cfct (Val1, Val2))              \
     : ((sizeof (__real__ (Val1)) == sizeof (Val1)        \
   && sizeof (__real__ (Val2)) == sizeof (Val2))        \
  ? (__typeof ((__tgmath_real_type (Val1)) 0        \
       + (__tgmath_real_type (Val2)) 0))        \
    Fct##f (Val1, Val2)             \
  : (__typeof ((__tgmath_real_type (Val1)) 0        \
       + (__tgmath_real_type (Val2)) 0))        \
    Cfct##f (Val1, Val2))))

Um... I just don't know what to say here. This is Cruel and Unusual.

SO what's going on here? Well, I looked at the docs for tgmath.h and found that this header defines a bunch of type-aware macros for basic functions like pow etc. that will determine whether the argument type is a double, float, etc. and then dispatch the call to the appropriate function. This is because C doesn't support overloading (though C++ does), so it has to be provided by the magic header file. The important detail here is that the function should only be called on arguments of type double, float, or complex versions of these types, and you're passing in an int. Since macro substitution is happening here, the compiler is not even looking at the cmath functions and instead just jumping into the C Macro From Hell which tries to introspect on the type.

In short, don't include this header file in C++! It's totally unnecessary in C++ because there's already support for overloaded functions, and there's a complex template there to handle complex numbers.

Hope this helps!

查看更多
Bombasti
3楼-- · 2019-06-21 13:43

As far as I can tell #include <tgmath.h> is the issue, and you can remove #include <math.h> as well, #include <cmath> should be sufficient.

If you include the proper C++ header file #include <ctgmath> it looks like it is ok as well.

查看更多
登录 后发表回答