I have a double variable i, that is converted to a void pointer named pointer:
double i = 3;
void *pointer = &i;
When I like to convert the void pointer back to double I used:
double p = *((double*) pointer);
I would like to convert the void pointer to the type I will send as a char*:
char* myType= typeid(i).name();//get the name of type of "i"
int p = *((myType*) pointer); // how to implement?
Is it possible?
instead of
char* myType= typeid(i).name();//get the name of type of "i"
int p = *((myType*) pointer); // how to implement?
use
typedef decltype(i) myType;
myType p = *((myType*) pointer);
or better:
typedef decltype(i) myType;
auto p = *reinterpret_cast<myType*>(pointer);
Works with c++11 or later. If you want to decltype on older c++ compilers, it is emulated in boost.
Edit. This is probably different from what you wanted to do, which I suppose is something like this:
void myFunction(void* unknownParam) {
typedef (realTypeOf unknownParam) RealType; // <-- this is not real c++
RealType &a = *reinterpret_cast<RealType*>(unknownParam)
//do stuff using 'a'
}
This is not possible in C++, but there is a reason: it doesn't make much sense.
And the reason is that for myFunction to be valid the //do stuff using 'a' part should be valid for whatever type RealType ends up being. As such, it cannot rely on any feature the RealType type have: it cannot use any of its methods, it cannot use any operator, it cannot even know whether it is a class or not. Basically, you cannot do anything more with it than what you would already be able to do on a void*, so giving the type a name doesn't really help you much.
A language feature that is similar to what you want (but not quite it) is type reflection, which is not present in C++, but you can find it in language such as Java, Objective-C or C#. Basically, you ask the object itself if it has a certain method, and eventually call it. An example in Objective-C
-(void)myFunction:(id)unknownParam {
if([unknownParam respondsToSelector:#selector(myMethod)])
[unknownParam performSelector:#selector(myMethod)]
}
C/C++ does not work well to interchange datatype like for example JavaScript variables
Format of int value will be different than double value format (floating point) in binary
You cannot get original data type using typeid after it has been casted to void*. Also note that typeid will have different output on different OS and compilers
double dValue = 77.7;
void* pValue = &dValue;
//output "pV" / pointer void (depending on compiler and OS)
std::cout << typeid(dValue).name() << std::endl;
To cast from void* using string you can make rules like following. Or you can try to use C++ template functions in specific cases.
int iOutValue = 0;
double dOutValue = 0;
char* name = "double";
if(!strcmp(name, "int"))
{
iOutValue = *((int*)pValue);
}
else if(!strcmp(name, "double"))
{
dOutValue = *((double*)pValue);
}
If instead of passing around void* you used some kind of variant type, you would be able to convert it back.
If you use a string to indicate the type you will need some kind of map from string to actual type. Although you can go from type to string, there is no conversion back.
Assuming you know your underlying data is always numeric in some way, there are ways to have special discrete variants that only contain numbers. The simplest would be to store a union of a 64-bit int and a double, and some flag indicating which one you have, and then a method to convert to any numeric type, asDouble(), asLong() etc.
Related
I am learning C++ using C++ Primer 5th edition. In particular, i read about void*. There it is written that:
We cannot use a void* to operate on the object it addresses—we don’t know that object’s type, and the type determines what operations we can perform on that object.
void*: Pointer type that can point to any nonconst type. Such pointers may not
be dereferenced.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*. Also, i am not sure if the above quoted statement from C++ Primer is technically correct because i am not able to understand what it is conveying. Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses". So can someone please provide some example to clarify what the author meant and whether he is correct or incorrect in saying the above statement.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*
It's indeed quite rare to need void* in C++. It's more common in C.
But where it's useful is type-erasure. For example, try to store an object of any type in a variable, determining the type at runtime. You'll find that hiding the type becomes essential to achieve that task.
What you may be missing is that it is possible to convert the void* back to the typed pointer afterwards (or in special cases, you can reinterpret as another pointer type), which allows you to operate on the object.
Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses"
Example:
int i;
int* int_ptr = &i;
void* void_ptr = &i;
*int_ptr = 42; // OK
*void_ptr = 42; // ill-formed
As the example demonstrates, we cannot modify the pointed int object through the pointer to void.
so since a void* has no size(as written in the answer by PMF)
Their answer is misleading or you've misunderstood. The pointer has a size. But since there is no information about the type of the pointed object, the size of the pointed object is unknown. In a way, that's part of why it can point to an object of any size.
so how can a int* on the right hand side be implicitly converted to a void*
All pointers to objects can implicitly be converted to void* because the language rules say so.
Yes, the author is right.
A pointer of type void* cannot be dereferenced, because it has no size1. The compiler would not know how much data he needs to get from that address if you try to access it:
void* myData = std::malloc(1000); // Allocate some memory (note that the return type of malloc() is void*)
int value = *myData; // Error, can't dereference
int field = myData->myField; // Error, a void pointer obviously has no fields
The first example fails because the compiler doesn't know how much data to get. We need to tell it the size of the data to get:
int value = *(int*)myData; // Now fine, we have casted the pointer to int*
int value = *(char*)myData; // Fine too, but NOT the same as above!
or, to be more in the C++-world:
int value = *static_cast<int*>(myData);
int value = *static_cast<char*>(myData);
The two examples return a different result, because the first gets an integer (32 bit on most systems) from the target address, while the second only gets a single byte and then moves that to a larger variable.
The reason why the use of void* is sometimes still useful is when the type of data doesn't matter much, like when just copying stuff around. Methods such as memset or memcpy take void* parameters, since they don't care about the actual structure of the data (but they need to be given the size explicitly). When working in C++ (as opposed to C) you'll not use these very often, though.
1 "No size" applies to the size of the destination object, not the size of the variable containing the pointer. sizeof(void*) is perfectly valid and returns, the size of a pointer variable. This is always equal to any other pointer size, so sizeof(void*)==sizeof(int*)==sizeof(MyClass*) is always true (for 99% of today's compilers at least). The type of the pointer however defines the size of the element it points to. And that is required for the compiler so he knows how much data he needs to get, or, when used with + or -, how much to add or subtract to get the address of the next or previous elements.
void * is basically a catch-all type. Any pointer type can be implicitly cast to void * without getting any errors. As such, it is mostly used in low level data manipulations, where all that matters is the data that some memory block contains, rather than what the data represents. On the flip side, when you have a void * pointer, it is impossible to determine directly which type it was originally. That's why you can't operate on the object it addresses.
if we try something like
typedef struct foo {
int key;
int value;
} t_foo;
void try_fill_with_zero(void *destination) {
destination->key = 0;
destination->value = 0;
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
try_fill_with_zero(foo_instance, sizeof(t_foo));
}
we will get a compilation error because it is impossible to determine what type void *destination was, as soon as the address gets into try_fill_with_zero. That's an example of being unable to "use a void* to operate on the object it addresses"
Typically you will see something like this:
typedef struct foo {
int key;
int value;
} t_foo;
void init_with_zero(void *destination, size_t bytes) {
unsigned char *to_fill = (unsigned char *)destination;
for (int i = 0; i < bytes; i++) {
to_fill[i] = 0;
}
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
int test_int;
init_with_zero(foo_instance, sizeof(t_foo));
init_with_zero(&test_int, sizeof(int));
}
Here we can operate on the memory that we pass to init_with_zero represented as bytes.
You can think of void * as representing missing knowledge about the associated type of the data at this address. You may still cast it to something else and then dereference it, if you know what is behind it. Example:
int n = 5;
void * p = (void *) &n;
At this point, p we have lost the type information for p and thus, the compiler does not know what to do with it. But if you know this p is an address to an integer, then you can use that information:
int * q = (int *) p;
int m = *q;
And m will be equal to n.
void is not a type like any other. There is no object of type void. Hence, there exists no way of operating on such pointers.
This is one of my favourite kind of questions because at first I was also so confused about void pointers.
Like the rest of the Answers above void * refers to a generic type of data.
Being a void pointer you must understand that it only holds the address of some kind of data or object.
No other information about the object itself, at first you are asking yourself why do you even need this if it's only able to hold an address. That's because you can still cast your pointer to a more specific kind of data, and that's the real power.
Making generic functions that works with all kind of data.
And to be more clear let's say you want to implement generic sorting algorithm.
The sorting algorithm has basically 2 steps:
The algorithm itself.
The comparation between the objects.
Here we will also talk about pointer functions.
Let's take for example qsort built in function
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
We see that it takes the next parameters:
base − This is the pointer to the first element of the array to be sorted.
nitems − This is the number of elements in the array pointed by base.
size − This is the size in bytes of each element in the array.
compar − This is the function that compares two elements.
And based on the article that I referenced above we can do something like this:
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
int main () {
int n;
printf("Before sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
return(0);
}
Where you can define your own custom compare function that can match any kind of data, there can be even a more complex data structure like a class instance of some kind of object you just define. Let's say a Person class, that has a field age and you want to sort all Persons by age.
And that's one example where you can use void * , you can abstract this and create other use cases based on this example.
It is true that is a C example, but I think, being something that appeared in C can make more sense of the real usage of void *. If you can understand what you can do with void * you are good to go.
For C++ you can also check templates, templates can let you achieve a generic type for your functions / objects.
I'm playing a bit with the C++ syntax to figure out a generalized way to keep track of an offset within a class, sort of like offsetof, but in a type-safe way and without #defines
I know that a template class can be template-parametrized with fields, besides types and constants. So I came out with this prototype:
#include <iostream>
template <typename class_type, typename field_type>
struct offsetter
{
offsetter(const char* name, field_type class_type::*field)
: name(name)
{
fprintf(stderr, "%zu\n", field);
}
const char* const name;
};
struct some_struct
{
float avg;
int min;
int max;
struct internal
{
unsigned flag;
int x;
} test;
char* name;
};
int main()
{
offsetter<some_struct, float>("%h", &some_struct::avg);
offsetter<some_struct, int>("%h", &some_struct::min);
offsetter<some_struct, char*>("%h", &some_struct::name);
offsetter<some_struct, some_struct::internal>("x", &some_struct::test);
return 0;
}
This code is actually able to print the field offset, but I'm not really sure on what I'm doing here. Indeed it feels utterly wrong to reference field without referring to an instance (foo.*field).
But it does the job: it prints the offset. My guess is that I'm hitting on some loophole though, since for instance I can't assign size_t offset = field.
I figured out I probably want something like this:
size_t offset = (&(std::declval<class_type>().*field) - &(std::declval<class_type>()))
Which however wont' work as I can't take the address of an xvalue:
taking address of xvalue (rvalue reference)
Is there any way to do this?
AFAIK there isn't a standard way of doing this. Even the standard offsetof is defined only for standard layout types.
What you are doing is UB. You are using the wrong specifier zu. There isn't much you can do with a member pointer. You can't even do pointer arithmetics on them, you can't convert to char* nor to an integer type.
Also if your assumption is that a member pointer is just an integer representing the offset from the beginning of the structure that is false, not only in theory, but also in practice. Having multiple inheritance and virtual inheritance made sure of that.
I'm working with a library that uses a C interface and several functions that pass a pointer to a struct as the output (not return).
The struct is something like
struct S {
short a;
short b;
union {
char cdata[5];
short sdata[5];
long ldata[5];
float fdata[5];
double dfdata[5];
} u;
}
I've written some template classes that can provide access to this in the form
auto parameter = MyClass<double>(constructor parameters);
parameter.SetValue(5.2); // Sets u.dfdata[0] = 5.2;
// other functions for changing index, or passing in a vector, etc
This is nice(ish) in that it abstracts away a lot of the required knowledge about structs, and only requires the user (still me, but whatever...) to know about the type of the parameter (double, float, long, short or char).
However, it's a compile time construct. The hardware I'm communicating with through this library is able to provide a function that has something like:
// renamed and tidied for ease of reading
// I don't have the source for this function, only docs
short GetParameter(short address, short* prevAddress, short* nextAddress,
S* parameter, Other* info);
where info can be parsed to tell me the type of the parameter. This would, if it were not compile time and different types, allow something like
std::vector<??> a;
a.push_back(MyClass<double>(args));
a.push_back(MyClass<short>(args));
where double and short can be read from the info struct as a short (0 = char, 1 = short...) and the other arguments can be read from the S struct.
I can build a std::vector<std::variant<MyClass<char>, MyClass<short>, ..., MyClass<double>>> but then trying to work out how to use a variant has left me confused if this is a good idea at all.
I want to be able to store sets of different types of parameters, for example for saving a complete configuration, but at the moment I think my functions are all compile-time calculations (variations on if constexpr(std::is_same_v<T, char>) { // do something with u.cdata[index] }).
If I want to be able to create lists with a single type, I can't (as far as I can work out) have virtual T ReadValue() or virtual void SetValue(T) because I can't use templating on virtual functions, and if I template the class (as I do now) then I have different (class) types which become hard to operate on.
An ideal solution would look something like
using valType = std::variant<char, short, long, float, double>;
using varType = std::variant<MyClass<char>, ..., MyClass<double>>;
// Read this from some file, or whatever
auto values = std::vector<valType> { 3, 2.6f, 17.2, 1523l };
std::vector<varType> paramList = MyFunctionThatReadsThroughParamToNextParam();
for (size_t i = 0; i < values.size(); i++) {
paramList[i].SetValue(values[i]);
// where the type contained in values[i] matches the type expected by paramList[i]
// ideally this would throw if the types were incorrect, but really
// any defined behaviour here would be great.
}
Is anything like this remotely possible?
I have enable to the user choosing the type of data he wants to use, for example if he wants to use long or double etc.
I would like to declare first the name of the variable then set its type. Is it possible in C++?
If I understood your question correctly, you want to do this:
declare variable;
// in the program:
variable = (int) anotherVariable;
Short answer:
No
Long answer:
a void * does exactly this, it needs to be explicitly converted to a different type before dereferencing. But this is not possible on variables that are not void *s.
void *variable = NULL;
int someIntVariable = 100;
int *someIntPointer = NULL;
variable = &someIntVariable;
someIntPointer = (int *)variable;
.. // but this seems unncessary.
Have a look at boost::variant, or, if you need only PODs, union. However keep in mind that this complicates many things.
enum VariantType {
USER_INT, USER_DOUBLE
};
union Variant {
int i;
double d;
}
int main() {
VariantType type;
Variant data;
type = getUserDataType();
switch(type) {
case USER_INT:
data.i = 42;
break;
case USER_DOUBLE:
data.d = 42.0;
break;
default:
break;
}
...or use some ready Variant implmementation.
Look into using VARIANT (if you're on Windows) or something similar on other platforms. The point of VARIANT is that it's a union that is capable of storing all kinds of data types but only 1 particular type at a given time. This way you can define a new generic variable type (VARIANT) ahead of time and then adapt its internal type at run-time, depending on user choice.
Using something like VARIANT comes at a price, though, since every operation that you do on it will have to check if the operation is correct for the current underlying type. VARIANT also uses more memory since the union has its own overhead (see the definition for details).
You may want to wrap variant operations in a class to simplify its usage. The nice thing about VARIANT as opposed to void* is that it gives you a lot more type safety and the code becomes a lot more readable.
Edit: as another answer pointed out, boos::variant is for this purpose.
Before i start i will divide the problem into two parties:
PART 1 :
In c++ to get type of data we can use typeid but it's give you the data as const char* ,and i want it to return the type of the data.
Example:
int data = 20 ;
float data2 = 3.14 ;
char *data3 = "hello world" ;
std::cout<< typeid(data).nam() << endl << endl ;
std::cout<< typeid(data2).nam() << endl << endl ;
std::cout<< typeid(data3).nam() << endl << endl ;
Now i have a function that get data from void* , and convert it to another type :
template <typename t >
void print (void *data )
{
boost::any _t = static_cast<t> (data);
cout << boost::any_cast<t> (_t) << endl << endl;
}
Now this works fine if you know your data type:
Example:
void *mydata = alloca(size_object) ;
void some_function_store_int_data_in_voidpointer( &mydata)
print <int> (mydata); // it's ok .
But this is impractical when you have lots of different datatypes, like this:
void somefunction(args &a , void *dest )
{
/*code returnd data */
}
enum args
{
_INT_ ,
_FLOAT_ ,
_CHARPOINTER_ ,
};
vector <void *test> myvector ;
myvector.resize (3) ;
void somefunction(_INT_ , myvector.at(0) ) ; // store int in void*
void somefunction(CHARPOINTER , myvector.at(0) ) ;// store char* in void*
void somefunction(_FLOAT_ , myvector.at(0) ) ;// store float in void*
print <int> (myvector.at(0));
print <char*> (myvector.at(1));
print <float> (myvector.at(2));
1 - If i use something like this
print <typeid(myvector.at(2))> (myvector.at(2));
i get an error because my data is float and I make it const char*
2 - Perhaps I can pass the type of every value if I have few data. This is OK. But what if I have 100 values from different types!
I am looking for something like: typeid but it' return the type not `const char*.
PART 2
because I have avector I will use a for_each algorithm like this:
for_each ( myvector.begin() , myvector.end() , print</*what i should pass her int , float ,char* ...or what , */>);
In the previous code I can pass only one type to the function so the data from the same type will print. Else the data that are not the same type will print, but completely wrong (Strange format).
So if I pass char* the int data will print completely wrong.
How can I do this differently?
How can I do this differently?
If your intention is to use same function for printing different data formats, then you can do it like this:
#include <iostream>
#include <algorithm>
#include <vector>
template <typename T> class Callback{
public:
void operator()(const T& value) const{
std::cout << value << std::endl;
}
};
template <typename T> Callback<typename T::value_type> makeCallback(const T&){
return Callback<T::value_type>();
}
int main(int argc, char** argv){
std::vector<int> ints(20);
std::vector<float> floats(20);
std::fill(ints.begin(), ints.end(), 0);
std::fill(floats.begin(), floats.end(), 0.0f);
std::for_each(ints.begin(), ints.end(), makeCallback(ints));
std::for_each(ints.begin(), ints.end(), makeCallback(floats));
return 0;
}
However, if you want to store several different data types in same std::vector, then you need "variant" types (like boost::variant, QVariant or similar), and there's no way around it.
I am looking for something like: typeid but it' return the type not `const char*.
In C++ "type" exists only at compilation stage, so you cannot return it, because it no longer exists once program has been compiled. There's no "type", so you can't return it.
So to get a "type" from object you need to implement some kind of "variant" type that can hold any object along with its type information, and pass that "variant" type around. One example of such system is QVariant in Qt 4.
AFAIK implementation of variant type goes like this: there is some kind of table for every type variant supports, you register all types variant class must support in that table. Table provides functions for creating type, destroying type, (de)serializing type, and possibly information about amount of memory required by one object of the type. The table can contain optional information you want, and you can convert entire registration procedure into macros+template combo. As you can see, this is not something that is done automatically by compiler, but something that involves plenty of hassle and must be taken care of by programmer. Also, things get much more fun if program must be able to take types developed externally (in plugins, etc).
As a result of language restrictions, the better idea would be to avoid situations when you need to "return type" when possible - variant systems aren't exactly difficult, but they aren't much fun either, due to all necessary sanity checks and conversions. Example problem: if you pass a string in variant type to a function that is supposed to take a float, should this function attempt to convert string to float? If conversion fails, should it crash/throw exception, or assume that variable has default value? If there's default value for failed conversions, what should it be and how should it be passed? And so on. This isn't a rocket science, but it is quite annoying to deal with.
For example, you could get rid of "void*" (if function takes pointer as an argument, then I would assume that poitner can be NULL/0. So "void*" arguments aren't exactly a good idea). arguments in your functions and use templates to make compiler generate code your want for types you actually use in your program. If templates are not an option, then you need some kind of "variant" type (preferably developed by somebody else), ... or you could switch to another language that provides type information you need. You don't have to use C++, any tool that does the job will do. Relying on RTTI also isn't a perfect solution, becuase if you manage to pass a pointer to something that does NOT contain type information, you'll get a non-standard exception (__non_rtti_object).
If you have a limited list of types you want to support, use boost::variant<int, float, const char*, ...> instead of boost::any (or void*). Then you can define a visitor to call the correct instantiation of the print function.
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
template <class T>
void print(T t)
{
std::cout << t << '\n';
}
struct print_visitor: boost::static_visitor<void>
{
template <class T>
void operator()(T t) const { print(t); }
};
int main()
{
typedef boost::variant<int, double, const char*> Variant;
std::vector<Variant> vec;
vec.push_back(13);
vec.push_back(3.14);
vec.push_back("Hello world");
BOOST_FOREACH(const Variant& v, vec) {
boost::apply_visitor(print_visitor(), v);
}
}
With a void* or a boost::any, I don't think you can do better than use a long if-chain to test all supported types.
C++ is a statically typed language, thus types only really exist in a meaningful way at the compile time, not at runtime. At runtime the best C++ can give you is RTTI which provides you with things like dynamic_cast<> and typeid(), which are however limited to giving you information along the inheritance hierarchy only, i.e. if you have
class Base
class DerivedA : public Base
class DerivedB : public Base
and you have a Base* or Base& you can find out if it's a Base, a DerivedA or a DerivedB. However in your case you only have a void*, which is completely outside of any inheritance hierarchy and thus has no type information associated with it. Thus all typeid() will tell you is that you have a void*, it won't tell you whatever type might hide behind it.
Furthermore a construct like:
print <typeid(myvector.at(2))> (myvector.at(2));
wouldn't work in C++ either, as the type for a template also needs to be known at compile time. Here however the type of .at(2) would only be known at runtime.
So to solve your problem you have to do the type handling yourself. Meaning you have to store the type along with the object you want to store, which would look something like this:
struct Value
{
enum { kInt, kString } type;
union {
int vInt;
char* vChar;
} value;
};
[...]
Value v;
v.type = Value::kInt;
v.value.vInt = 5;
switch(v.type)
{
case Value::kInt:
// do int specific stuff
break;
case Value::kString:
// do string specific stuff
break;
}
The boost::variant<> class that visitor mentioned provides basically the above in a nicely packaged way.
Another thing worth to mention is decltype, decltype is new in C++11 standard and allows you to get the actual type of an object and thus you can write code like:
int a;
decltype(a) b;
Where b gets the same type as a, i.e. int. This sounds exactly like what you want, but it is not, decltype() has the same restrictions as before. It can only work when the type is already known at compile time, it can't do anything with types only known at runtime. Thus it will not work in your situation and is only really useful when doing some more complex template programming.
Long story short, use boost::variant<> or write yourself a class that works in a similar way.
PART 1: I'm not quite sure I fully understand your query, but have you looked at the header file <typeinfo>? struct type_info may be what you're looking for.