C++ – invalid conversion from ‘const void*’ to ‘PVOID {aka void*}’ [-fpermissive]


I am writing a program (well… using sample code form Tektronix) to test the message exchange over the network to our spectrum analyser in our lab.

A header file called "decl-32.h" has been provided, and in the sample code is the following line, along with the error it produces:

ibwrt(GpibDevice, "SYSTem:ERRor:ALL?", strlen("SYSTem:ERRor:ALL?"));

"invalid conversion from 'const void*' to 'PVOID {aka void*}' [-fpermissive]"

Within the header file, the following line of code is highlighted as erroneous, along with the following error:

extern int __stdcall ibwrt (int ud, PVOID buf, long cnt);

"initializing argument 2 of 'int ibwrt(int, PVOID, long int)' [-fpermissive]"

The problem is that I am unfamiliar with such complex variable definitions, uses and conversions.

Could somebody be kind enough to offer me some advice? I'm sure this would be relevant to many others who are unfamiliar with such variable types and conversions, etc.

Thank you in advance!

Best Solution

The second parameter to ibwrt is PVOID which is a typedef for void*. In C++, pointer types are implicitly convertible to void*, but, as with all other types, the conversion is not allowed to drop a qulifier. That is, conversion from const char* (which is the type string literals decay to) to void* is illegal. Hence the error.

In C language, which is where the code is coming from, string literals decay to char* and your line will compile as is. The reason is historical - early implementations of C didn't have const keyword.

To fix it, you can cast the const away with a const_cast:

const char* s = "SYSTem:ERRor:ALL?";
ibwrt(GpibDevice, const_cast<char*>(s), strlen("SYSTem:ERRor:ALL?"));

You need to trust the function that it'll not attempt to modify the string literal through the pointer you passed it, otherwise it would invoke undefined behaviour. Seems like a safe assumption in this case (or maybe not, the parameter is named buf, mind you!), but if you want to be sure, do a copy of the string like @MikeSeymour shows in his answer.

Related Question