Jump to content
  • Advertisement
lride

C++ Xor contents of an object with virtual function

This topic is 374 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

struct Base
{
	virtual void func() = 0;
};
struct A : Base
{
	void func()
	{
		std::cout << "a: " << a << "\n";
	}
	int a;
};


int main()
{
	A a;
	a.a = 1;
	A a2 = a;

	A a3;
	char * ap = reinterpret_cast<char*>(&a);
	char * ap2 = reinterpret_cast<char*>(&a2);
	char * ap3 = reinterpret_cast<char*>(&a3);

	for (int i = 0; i < sizeof(A); ++i)
		*(ap3 + i) = *(ap + i) ^ *(ap2 + i);

	Base * b = &a3;
	b->func();
	

}

 

I want to bitwise xor the contents of an object with virtual functions like above.

But I think i get a crash in above scenario because I xor'd the vptr too.

Is there a way to achieve what I want?

Edited by lride

Share this post


Link to post
Share on other sites
Advertisement

I want to be able to call a virtual function on the xor'd object.

The reason is I'm trying to implement delta compression for compressing snapshots for a multiplayer game.

I need to xor the contents of two objects and then call a virtual function to pack the bits.

Share this post


Link to post
Share on other sites

I think you need to answer for us and for yourself; what does an XOR of the bits implementing an object in memory have to do with delta-compressing the concepts and values which the object contains?

You don't measure the difference between two 2D vectors implemented by `struct Vector{double x,y;}` by taking the XOR of the bits which implement the two IEEE 754 Double-Precision floating-point values... you calculate a new vector which's components are the difference between the components of the two vectors.

Edited by Wyrframe
typo

Share this post


Link to post
Share on other sites

This is the way how I do delta compression:

All objects' information is represented in integers.

I xor the two objects and I get lots of 0s. Then I do run length encoding.

 

I think I can solve this problem by adding virtual void * data(), and virtual int size() methods.

Share this post


Link to post
Share on other sites

C++ objects are not just a pile of bits - you can't just cast them to another type and do bitwise operations of them. This is undefined behaviour. You may be able to get it to work by accounting for all the details such as vtables, but, it will still be undefined behaviour and your compiler will still be allowed to fuck you over. 

Either use plain old data structures that can safety be bitwise modified, or, implement a "delta compare" virtual function. 

Share this post


Link to post
Share on other sites
struct BaseNetObj
{
    std::vector<char> data;
    std::function<void()> func;
};

struct NetPerson
{
    void say()
    {
        std::cout << a << b << c << "\n";
    }
    int a;
    int b;
    int c;
};

template <typename T>
BaseNetObj makeBase()
{
    BaseNetObj obj;
    obj.data.resize(sizeof(T));
    obj.func = std::bind(&T::say, (T*)obj.data.data());
    return obj;
}

int main()
{
    BaseNetObj obj0 = makeBase<NetPerson>();
    BaseNetObj obj1 = makeBase<NetPerson>();
    BaseNetObj obj2 = makeBase<NetPerson>();

    NetPerson * p0 = (NetPerson*)obj0.data.data();
    p0->a = p0->b = p0->c = 1;

    NetPerson * p1 = (NetPerson*)obj1.data.data();
    p1->a = p1->b = p1->c = 1;
    
    obj0.func(); //111
    obj1.func(); //111


    for (int i = 0; i < obj0.data.size(); ++i)
    {
        obj2.data = obj0.data ^ obj1.data;
    }
    obj2.func(); //000
}

I think the above should do it. No inheritance, virtual functions. The base class holds the raw data in a vector. I can still do emulate polymorphism with std::function.

Share this post


Link to post
Share on other sites

The claim above was that it was an attempt to improve compression of delta encoding.

The only thing I can come up with, based on the talk of xor'ing for delta-encoded snapshots, that makes me suspect that he's trying to use a frame-of-reference encoding used in some video and audio files, where you've got a small set of integer values with only slight variation and with a limited number of available bits. You can isolate the number of actual bits used, use some zig-zag encoding to combine the bits, and xor in the zig-zag to avoid subtractions with negative numbers, adding in the xor'ed value instead.

The other reason I suspect that's the purpose is that Google's "protocol buffers" uses that as a tiny piece of their encoding. Since their protocol buffer encoding is rapidly becoming more popular, people read about it and then attempt to implement it without fully understanding the details.  

Or it could be some other reason that he's trying to do it, something else about delta-encoded snapshots that doesn't immediately come to mind.

Anyway, for a situation like the one described, the best approach is probably for the objects themselves to implement a delta system, and to use a good bit-packer library to encode the values.  Thus a system could say there are zero bits different, or store a 2-bit pattern if it is different within 4, or store a 3-bit pattern if it is different within 8, etc., so small changes require even fewer bytes in the stream.  That stream can then be compressed with any of the major general-purpose stream-based compression libraries like gzip or zlib or similar.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!