Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to avoid implicit conversion to void*?

I'm using an API that accepts void* in certain functions. I frequently accidentally pass the wrong pointer type to the function, and of course it compiles fine, but doesn't work at runtime.

Is there a way to disable implicit conversion to void* for pointers to a certain class?

like image 553
AILien Avatar asked Aug 05 '21 21:08

AILien


People also ask

Is implicit type conversion bad?

Implicit conversions allow the compiler to treat values of a type as values of another type. There's at least one set of scenarios in which this is unambiguously bad: non-total conversions. That is, converting an A to a B when there exists A s for which this conversion is impossible.

Can Void be converted to int?

You're return ing the value of int sum by setting a void * address to it. In this case, the address is not valid. But, if you keep that in mind and get the value of sum by casting a void * to int it will work.

What happens in implicit conversion?

An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.

How do you use implicit conversions?

An implicit conversion from type S to type T is defined by an implicit value which has function type S => T , or by an implicit method convertible to a value of that type. Implicit conversions are applied in two situations: If an expression e is of type S , and S does not conform to the expression's expected type T .


1 Answers

Is there any way to disable implicit conversion to void* for pointers to a certain class?

No, you can't prevent the implicit conversion, but you could wrap the API function(s) in proxy functions that checks types at compile time and approve/disapprove them there.

Example:

#include <iostream> #include <string> #include <type_traits>  void api(void* p) { // your original API     std::cout << "void* " << p << '\n'; }  template<class T> void api_wrapper(T* p) { // your wrapper     // let constness fail in the original api instead of in the static_assert:     using type = std::remove_const_t<T>*;      static_assert(         // add your approved types here         std::is_convertible_v<type, std::ostream*> ||         std::is_convertible_v<type, std::string*>,         "Not an approved type"     );     api(p); }  int main() {     std::string foo;     api_wrapper(&std::cout);     api_wrapper(&foo);     //api_wrapper(&std::cin); // compile time error "Not an approved type" } 

If the set of pointer types that you would like to disapprove is very small, then instead of listing all the approved types in the static_assert, just list the disapproved types and adjust the boolean logic:

    static_assert(         // add your disapproved types here         not std::is_convertible_v<type, std::ostream*> &&         not std::is_convertible_v<type, std::string*>,         "Not an approved type"     ); 
like image 76
Ted Lyngmo Avatar answered Sep 20 '22 20:09

Ted Lyngmo