“'void*' is not a pointer-to-object type” in code with no void*'s?

久未见 提交于 2019-12-23 09:50:04

问题


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;
}

回答1:


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.




回答2:


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!



来源:https://stackoverflow.com/questions/16705016/void-is-not-a-pointer-to-object-type-in-code-with-no-voids

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!