Another void* topic; I just have to ask because I am confused - c++11

Ok, muddling though Stack on the particulars about void*, books like The C Programming Language (K&R) and The C++ Programming Language (Stroustrup). What have I learned? That void* is a generic pointer with no type inferred. It requires a cast to any defined type and printing void* just yields the address.
What else do I know? void* can't be dereferenced and thus far remains the one item in C/C++ from which I have discovered much written about but little understanding imparted.
I understand that it must be cast such as *(char*)void* but what makes no sense to me for a generic pointer is that I must somehow already know what type I need in order to grab a value. I'm a Java programmer; I understand generic types but this is something I struggle with.
So I wrote some code
typedef struct node
{
void* data;
node* link;
}Node;
typedef struct list
{
Node* head;
}List;
Node* add_new(void* data, Node* link);
void show(Node* head);
Node* add_new(void* data, Node* link)
{
Node* newNode = new Node();
newNode->data = data;
newNode->link = link;
return newNode;
}
void show(Node* head)
{
while (head != nullptr)
{
std::cout << head->data;
head = head->link;
}
}
int main()
{
List list;
list.head = nullptr;
list.head = add_new("My Name", list.head);
list.head = add_new("Your Name", list.head);
list.head = add_new("Our Name", list.head);
show(list.head);
fgetc(stdin);
return 0;
}
I'll handle the memory deallocation later. Assuming I have no understanding of the type stored in void*, how do I get the value out? This implies I already need to know the type, and this reveals nothing about the generic nature of void* while I follow what is here although still no understanding.
Why am I expecting void* to cooperate and the compiler to automatically cast out the type that is hidden internally in some register on the heap or stack?

I'll handle the memory deallocation later. Assuming I have no understanding of the type stored in void*, how do I get the value out?
You can't. You must know the valid types that the pointer can be cast to before you can dereference it.
Here are couple of options for using a generic type:
If you are able to use a C++17 compiler, you may use std::any.
If you are able to use the boost libraries, you may use boost::any.

Unlike Java, you are working with memory pointers in C/C++. There is no encapsulation whatsoever. The void * type means the variable is an address in memory. Anything can be stored there. With a type like int * you tell the compiler what you are referring to. Besides the compiler knows the size of the type (say 4 bytes for int) and the address will be a multiple of 4 in that case (granularity/memory alignment). On top, if you give the compiler the type it will perform consistency checks at compilation time. Not after. This is not happening with void *.
In a nutshell, you are working bare metal. The types are compiler directives and do not hold runtime information. Nor does it track the objects you are dynamically creating. It is merely a segment in memory that is allocated where you can eventually store anything.

The main reason to use void* is that different things may be pointed at. Thus, I may pass in an int* or Node* or anything else. But unless you know either the type or the length, you can't do anything with it.
But if you know the length, you can handle the memory pointed at without knowing the type. Casting it as a char* is used because it is a single byte, so if I have a void* and a number of bytes, I can copy the memory somewhere else, or zero it out.
Additionally, if it is a pointer to a class, but you don't know if it is a parent or inherited class, you may be able to assume one and find out a flag inside the data which tells you which one. But no matter what, when you want to do much beyond passing it to another function, you need to cast it as something. char* is just the easiest single byte value to use.

Your confusion derived from habit to deal with Java programs. Java code is set of instruction for a virtual machine, where function of RAM is given to a sort of database, which stores name, type, size and data of each object. Programming language you're learning now is meant to be compiled into instruction for CPU, with same organization of memory as underlying OS have. Existing model used by C and C++ languages is some abstract built on top of most of popular OSes in way that code would work effectively after being compiled for that platform and OS. Naturally that organization doesn't involve string data about type, except for famous RTTI in C++.
For your case RTTI cannot be used directly, unless you would create a wrapper around your naked pointer, which would store the data.
In fact C++ library contains a vast collection of container class templates that are useable and portable, if they are defined by ISO standard. 3/4 of standard is just description of library often referred as STL. Use of them is preferable over working with naked pointers, unless you mean to create own container for some reason. For particular task only C++17 standard offered std::any class, previously present in boost library. Naturally, it is possible to reimplement it, or, in some cases, to replace by std::variant.

Assuming I have no understanding of the type stored in void*, how do I get the value out
You don't.
What you can do is record the type stored in the void*.
In c, void* is used to pass around a binary chunk of data that points at something through one layer of abstraction, and recieve it at the other end, casting it back to the type that the code knows it will be passed.
void do_callback( void(*pfun)(void*), void* pdata ) {
pfun(pdata);
}
void print_int( void* pint ) {
printf( "%d", *(int*)pint );
}
int main() {
int x = 7;
do_callback( print_int, &x );
}
here, we forget thet ype of &x, pass it through do_callback.
It is later passed to code inside do_callback or elsewhere that knows that the void* is actually an int*. So it casts it back and uses it as an int.
The void* and the consumer void(*)(void*) are coupled. The above code is "provably correct", but the proof does not lie in the type system; instead, it depends on the fact we only use that void* in a context that knows it is an int*.
In C++ you can use void* similarly. But you can also get fancy.
Suppose you want a pointer to anything printable. Something is printable if it can be << to a std::ostream.
struct printable {
void const* ptr = 0;
void(*print_f)(std::ostream&, void const*) = 0;
printable() {}
printable(printable&&)=default;
printable(printable const&)=default;
printable& operator=(printable&&)=default;
printable& operator=(printable const&)=default;
template<class T,std::size_t N>
printable( T(&t)[N] ):
ptr( t ),
print_f( []( std::ostream& os, void const* pt) {
T* ptr = (T*)pt;
for (std::size_t i = 0; i < N; ++i)
os << ptr[i];
})
{}
template<std::size_t N>
printable( char(&t)[N] ):
ptr( t ),
print_f( []( std::ostream& os, void const* pt) {
os << (char const*)pt;
})
{}
template<class T,
std::enable_if_t<!std::is_same<std::decay_t<T>, printable>{}, int> =0
>
printable( T&& t ):
ptr( std::addressof(t) ),
print_f( []( std::ostream& os, void const* pt) {
os << *(std::remove_reference_t<T>*)pt;
})
{}
friend
std::ostream& operator<<( std::ostream& os, printable self ) {
self.print_f( os, self.ptr );
return os;
}
explicit operator bool()const{ return print_f; }
};
what I just did is a technique called "type erasure" in C++ (vaguely similar to Java type erasure).
void send_to_log( printable p ) {
std::cerr << p;
}
Live example.
Here we created an ad-hoc "virtual" interface to the concept of printing on a type.
The type need not support any actual interface (no binary layout requirements), it just has to support a certain syntax.
We create our own virtual dispatch table system for an arbitrary type.
This is used in the C++ standard library. In c++11 there is std::function<Signature>, and in c++17 there is std::any.
std::any is void* that knows how to destroy and copy its contents, and if you know the type you can cast it back to the original type. You can also query it and ask it if it a specific type.
Mixing std::any with the above type-erasure techinque lets you create regular types (that behave like values, not references) with arbitrary duck-typed interfaces.

Related

C++ Check if generic object has member function matching signature

first post, so hopefully not violating any etiquette. Feel free to give suggestions for making the question better.
I've seen a few posts similar to this one: Check if a class has a member function of a given signature, but none do quite what I want. Sure it "works with polymorphism" in the sense that it can properly check subclass types for the function that comes from a superclass, but what I'd like to do is check the object itself and not the class. Using some (slightly tweaked) code from that post:
// Somewhere in back-end
#include <type_traits>
template<typename, typename T>
struct HasFunction {
static_assert(integral_constant<T, false>::value,
"Second template parameter needs to be of function type."
);
};
template<typename C, typename Ret, typename... Args>
class HasFunction<C, Ret(Args...)> {
template<typename T>
static constexpr auto check(T*) -> typename is_same<
decltype(declval<T>().myfunc(declval<Args>()...)), Ret>::type;
template<typename>
static constexpr false_type check(...);
typedef decltype(check<C>(0)) type;
public:
static constexpr bool value = type::value;
};
struct W {};
struct X : W { int myfunc(double) { return 42; } };
struct Y : X {};
I'd like to have something like the following:
// somewhere else in back-end. Called by client code and doesn't know
// what it's been passed!
template <class T>
void DoSomething(T& obj) {
if (HasFunction<T, int(double)>::value)
cout << "Found it!" << endl;
// Do something with obj.myfunc
else cout << "Nothin to see here" << endl;
}
int main()
{
Y y;
W* w = &y; // same object
DoSomething(y); // Found it!
DoSomething(*w); // Nothin to see here?
}
The problem is that the same object being viewed polymorphically causes different results (because the deduced type is what is being checked and not the object). So for example, if I was iterating over a collection of W*'s and calling DoSomething I would want it to no-op on W's but it should do something for X's and Y's. Is this achievable? I'm still digging into templates so I'm still not quite sure what's possible but it seems like it isn't. Is there a different way of doing it altogether?
Also, slightly less related to that specific problem: Is there a way to make HasFunction more like an interface so I could arbitrarily check for different functions? i.e. not have ".myfunc" concrete within it? (seems like it's only possible with macros?) e.g.
template<typename T>
struct HasFoo<T> : HasFunction<T, int foo(void)> {};
int main() {
Bar b;
if(HasFoo<b>::value) b.foo();
}
Obviously that's invalid syntax but hopefully it gets the point across.
It's just not possible to perform deep inspection on a base class pointer in order to check for possible member functions on the pointed-to type (for derived types that are not known ahead of time). Even if we get reflection.
The C++ standard provides us no way to perform this kind of inspection, because the kind of run time type information that is guaranteed to be available is very limited, basically relegated to the type_info structure.
Your compiler/platform may provide additional run-time type information that you can hook into, although the exact types and machinery used to provide RTTI are generally undocumented and difficult to examine (This article by Quarkslab attempts to inspect MSVC's RTTI hierarchy)

Access variables in struct from void pointer

I was wondering if there is a way to access a data member within a struct that is being pointed to by a void*? What I'm trying to explain will hopefully be more apparent in my example code:
int main()
{
struct S
{
int val;
};
S s;
s.val = 5;
void* p;
p = malloc(sizeof(S));
*(struct S*) p = s;
std::cout<< *(struct S*)p.val << std::endl;
}
I have ran this exact code casting p as *(int*)p and it printed fine, however, using exact code above results in a compilation error. Haven't been able to find an example that quite accomplishes this task. Is it possible to access the data members of the struct after it is casted? why or why not? if so, how?
The . operator has higher precedence than a C-style cast. So *(struct S*)p.val is treated as *((struct S*)(p.val)), which doesn't make sense since p is a pointer and does not have members.
So you need parentheses to specify what you intended:
std::cout<< (*(struct S*)p).val << std::endl;
Or equivalently,
std::cout<< static_cast<S*>(p)->val << std::endl;
[But also: the statement *(struct S*) p = s; technically has undefined behavior, even though all most implementations will allow it. This is because C++ has rules about when an object is created, and there was no object of type S previously at that address, and assignment does not create an object except for some cases involving union members. A similar statement that does not have this problem would be new(p) S{s};.
Also also: use of malloc or void* is usually not a good idea in C++ in the first place. malloc should only be used when interfacing with a C library that requires it. Anything for which void* seems useful can probably be done more safely using templates. In a few cases a void* might be the only way to do something or "cleverly" avoid code duplication or something, but still use it sparingly and always with extreme caution.]

How to avoid C++ code bloat issued by template instantiation and symbol table?

I'd started a bare-metal (Cortex-M) project some years ago. At project setup we decided to use gcc toolchain with C++11 / C++14 etc. enabled and even for using C++ exceptions and rtti.
We are currently using gcc 4.9 from launchpad.net/gcc-arm-embedded (having some issue which prevent us currently to update to a more recent gcc version).
For example, I'd wrote a base class and a derived class like this (see also running example here):
class OutStream {
public:
explicit OutStream() {}
virtual ~OutStream() {}
OutStream& operator << (const char* s) {
write(s, strlen(s));
return *this;
}
virtual void write(const void* buffer, size_t size) = 0;
};
class FixedMemoryStream: public OutStream {
public:
explicit FixedMemoryStream(void* memBuffer, size_t memBufferSize): memBuffer(memBuffer), memBufferSize(memBufferSize) {}
virtual ~FixedMemoryStream() {}
const void* getBuffer() const { return memBuffer; }
size_t getBufferSize() const { return memBufferSize; }
const char* getText() const { return reinterpret_cast<const char*>(memBuffer); } ///< returns content as zero terminated C-string
size_t getSize() const { return index; } ///< number of bytes really written to the buffer (max = buffersize-1)
bool isOverflow() const { return overflow; }
virtual void write(const void* buffer, size_t size) override { /* ... */ }
private:
void* memBuffer = nullptr; ///< buffer
size_t memBufferSize = 0; ///< buffer size
size_t index = 0; ///< current write index
bool overflow = false; ///< flag if we are overflown
};
So that the customers of my class are now able to use e.g.:
char buffer[10];
FixedMemoryStream ms1(buffer, sizeof(buffer));
ms1 << "Hello World";
Now I'd want to make the usage of the class a bit more comfortable and introduced the following template:
template<size_t bufferSize> class FixedMemoryStreamWithBuffer: public FixedMemoryStream {
public:
explicit FixedMemoryStreamWithBuffer(): FixedMemoryStream(buffer, bufferSize) {}
private:
uint8_t buffer[bufferSize];
};
And from now, my customers can write:
FixedMemoryStreamWithBuffer<10> ms2;
ms2 << "Hello World";
But from now, I'd observed increasing size of my executable binary. It seems that gcc added symbol information for each different template instantiation of FixedMemoryStreamWithBuffer (because we are using rtti for some reason).
Might there be a way to get rid of symbol information only for some specific classes / templates / template instantiations?
It's ok to get a non portable gcc only solution for this.
For some reason we decided to prefer templates instead of preprocessor macros, I want to avoid a preprocessor solution.
First of all, keep in mind that compiler also generates separate v-table (as well as RTTI information) for every FixedMemoryStreamWithBuffer<> type instance, as well as every class in the inheritance chain.
In order to resolve the problem I'd recommend using containment instead of inheritance with some conversion function and/or operator inside:
template<size_t bufferSize>
class FixedMemoryStreamWithBuffer
{
uint8_t buffer[bufferSize];
FixedMemoryStream m_stream;
public:
explicit FixedMemoryStreamWithBuffer() : m_stream(m_buffer, bufferSize) {}
operator FixedMemoryStream&() { return m_stream; }
FixedMemoryStream& toStream() { return m_stream; }
};
Yes, there's a way to bring the necessary symbols almost down to 0: using the standard library. Your OutStream class is a simplified version of std::basic_ostream. Your OutStream::write is really just std::basic_ostream::write and so on. Take a look at it here. Overflow is handled really closely, though, for completeness' sake, it also deals with underflow i.e. the need for data retrieval; you may leave it as undefined (it's virtual too).
Similarly, your FixedMemoryStream is std::basic_streambuf<T> with a fixed-size (a std::array<T>) get/put area.
So, just make your classes inherit from the standard ones and you'll cut off on binary size since you're reusing already declared symbols.
Now, regarding template<size_t bufferSize> class FixedMemoryStreamWithBuffer. This class is very similar to std::array<std::uint8_t, bufferSize> as for the way memory is specified and acquired. You can't optimize much about that: each instantiation is a different type with all what that implies. The compiler cannot "merge" or do anything magic about them: each instantiation must have its own type.
So either fall back on std::vector or have some fixed-size specialized chunks, like 32, 128 etc. and for any values in between would choose the right one; this can be achieved entirely at compile-time, so no runtime cost.

C++11 Pointer (void**)&data

I'm still learning C++, and I'm doing some API work, but I'm, having trouble parsing this pointer arrangement.
void* data;
res = npt.receive(0x1007, params, 1, response, (void**)&data, size);
uint32_t* op = (uint32_t*)data;
uint32_t num = *op;
op++;
Can anyone explain what is going on with that void pointer? I see it being defined, it does something in the res line(maybe initialized?), then it's copied to an uint32 pointer, and dereferenced in num. Can anyone help me parse the (void**)&data declaration?
Pay attention when you use the void pointer:
The void type of pointer is a special type of pointer. In C++, void represents the absence of type. Therefore, void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties).
This gives void pointers a great flexibility, by being able to point to any data type, from an integer value or a float to a string of characters. In exchange, they have a great limitation: the data pointed to by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason, any address in a void pointer needs to be transformed into some other pointer type that points to a concrete data type before being dereferenced.
From C++ reference
Firstly: What is npt?
Secondly: Guessing what npt could be some explanation:
// Declare a pointer to void named data
void* data;
// npt.receive takes as 5th parameter a pointer to pointer to void,
// which is why you provide the address of the void* using &data.
// The void ** appears to be unnecessary unless the data type of the
// param is not void **
// What is "npt"?
res = npt.receive(0x1007, params, 1, response, (void**)&data, size);
// ~.receive initialized data with contents.
// Now make the uint32_t data usable by casting void * to uint32_t*
uint32_t* op = (uint32_t*)data;
// Use the data by dereferencing it.
uint32_t num = *op;
// Pointer arithmetic: Move the pointer by sizeof(uint32_t).
// Did receive fill in an array?
op++;
Update
Signature of receive is:
<whatever return type> receive(uint16_t code, uint32_t* params, uint8_t nparam, Container& response, void** data, uint32_t& size)
So the data parameter is of type void** already so the explicit type cast to void** using (void**) is not necessary.
Considering the usage, the received data appears to be an array of uint32_t values IN THIS CASE!
Void as a type means no type and no type information regarding size and alignment is available, but is mandatory for lexical and syntactical consistency.
In conjunction with the *, it can be used as a pointer to data of unknown type and must be explicitly cast to another type (adds type information) before any use.
You usually have a void* or void** in an API, if you dont know the specific data type or only received plain byte data.
To understand this please read up C type erasure using void*
Please read up as basics before:
Dynamically allocated C arrays.
Pointers and Pointer Arithmetics.
From the code, ntp.receive tells you whether it receives anything successfully in the return code but it also needs to give you what it receives. It has a pointer that it wants to pass back, so you have to tell it where that pointer is so that it can fill it, hence (void **), a pointer to a pointer, being the address of your pointer, &data.
When you have received it, you know as the developer that what it points to is actually a uint_32 value so you copy the void pointer into one that points to a uint_32. In fact, this step is unnecessary since you could have cast the uint_32 pointer to void** in the above call but we'll let that slide.
Now that you have told the compiler that the pointer points to a 32 bit number, you can take the number on the other end of that pointer (*op) and store it in a local variable. Again, unnecessary, as *op could be used anywhere num is subsequently used.
Hope this helps.

Is there a way to use Boost serialization on stl functional

I have an stl functional std::function<int(int,int)> fcn_ as a member field of a class. Is there a way to serialize it using boost serialization? If I do the following
template<class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & fcn_;
}
I got the error
/opt/local/include/boost/serialization/access.hpp:118:9: error: 'class std::function<int(int, int)>' has no member named 'serialize'
Is there a header file (say something like<boost/serialization/vector.hpp>) I can include that implements serialize for std::function? Or is there an easy way to implement one myself?
Thanks!
I haven't had a look at how Boost serialization works, but here is a possible approach.
template<typename T>
std::ostream& serialize(std::ostream& out, const std::function<T>& fn)
{
using decay_t = typename std::decay<T>::type;
if(fn.target_type() != typeid(decay_t)) throw std::runtime_error(std::string(typeid(decay_t).name()) + " != " + fn.target_type().name());
const auto ptr = fn.template target<decay_t>();
out << reinterpret_cast<void*>(*ptr);
return out;
}
template<typename T>
std::istream& deserialize(std::istream& in, std::function<T>& fn)
{
using decay_t = typename std::decay<T>::type;
void* ptr = nullptr;
in >> ptr;
fn = reinterpret_cast<decay_t>(ptr);
return in;
}
Please note that this will not work if you are storing lambdas or function objects in your std::functions (as per http://en.cppreference.com/w/cpp/utility/functional/function/target).
A running example can be found coliru.
You could require my_serializable_function<int(int,int)> which knows how to self-describe and reconstruct from such a descriptor.
In other words: you write the code yourself.
Alternatively, you might look at a scripting engine, which already contains stuff like this (Boost Python, several Lua bindings, v8 engine etc.). Though each comes with their own set of trade-offs and might be overkill.
Thanks to Tom and sehe's response. After some research, I realized what I had in mind is not really possible in C++ --- it is generally not possible to serialize an std::function object. By "serialize", I mean being able to transfer (read/write) the object as a byte stream from one program to another program, or to the same program but a different invocation on the same or a different machine. The links below has more discussion about this topic:
Serializing function objects
Can std::function be serialized?

Resources