This example :
#include <iostream>
#include <cstring>
struct A
{
int a;
bool b;
};
bool foo( const A a1, const A a2 )
{
return ( 0 == std::memcmp( &a1, &a2, sizeof( A ) ) );
}
int main()
{
A a1 = A();
a1.a = 5;a1.b = true;
A a2 = A();
a2.a = 5;a2.b = true;
std::cout<<std::boolalpha << foo( a1, a2 ) << std::endl;
}
is going to produce false
, because of padding.
I do not have access to the foo
function, and I can not change the way the comparison is done.
Assuming a bool
occupies 1 byte (that is true on my system), if I change the struct A
to this :
struct A
{
int a;
bool b;
char dummy[3];
};
then it works fine on my system (the output is true
).
Is there anything else I could do to fix the above problem (get the true
output)?
A POD type is a C++ type that has an equivalent in C, and that uses the same rules as C uses for initialization, copying, layout, and addressing. As an example, the C declaration struct Fred x; does not initialize the members of the Fred variable x.
The struct MyStruct has no user-defined ctor, dtor, etc and hence is a POD.
Learning pods — also called “pandemic pods,” micro-schools or nano-schools — are small groups of students (typically three to 10 children) who learn together outside the classroom but still in person. Some pods are hiring tutors to teach a child's school curriculum; some pods are sharing teaching duties among parents.
In computer science and object-oriented programming, a passive data structure (PDS, also termed a plain old data structure, or plain old data, POD) is a term for a record, to contrast with objects.
The first one is not working because of padding in the struct. The padding is having different bit patterns for both objects.
If you use memset
to set all the bits in the object before using it, then it will work:
A a1;
std::memset(&a1, 0, sizeof(A));
a1.a = 5;a1.b = true;
A a2;
std::memset(&a2, 0, sizeof(A));
a2.a = 5;a2.b = true;
Online demos:
By the way, you can write operator<
, operator==
etc, for PODs also.
Since C++11 we can use tuples for simple POD comparison (tuples use lexicographical comparison for >
, <
, >=
and <=
operators, more info on that: https://en.cppreference.com/w/cpp/utility/tuple/operator_cmp ) :
#include <iostream>
#include <tuple>
struct Point {
int x;
int y;
int z;
};
auto pointToTuple(const Point& p) {
return std::make_tuple(p.x, p.y, p.z);
}
bool operator==(const Point& lhs, const Point& rhs ) {
return pointToTuple(lhs) == pointToTuple(rhs);
}
bool operator<(const Point& lhs, const Point& rhs ) {
return pointToTuple(lhs) < pointToTuple(rhs);
}
int main()
{
Point a{1, 2, 3};
Point b{1, 2, 3};
Point c{2, 2, 2};
std::cout << (pointToTuple(a) == pointToTuple(b) ? "true" : "false") << "\n"; //true
std::cout << (pointToTuple(a) == pointToTuple(c) ? "true" : "false") << "\n"; //false
std::cout << (a == b ? "true" : "false") << "\n"; //true
std::cout << (a == c ? "true" : "false") << "\n"; //false
std::cout << (a < b ? "true" : "false") << "\n"; //false
std::cout << (a < c ? "true" : "false") << "\n"; //true
}
C++20 should bring us default comparisons (https://en.cppreference.com/w/cpp/language/default_comparisons). So if class defines operator<=>
as defaulted, compiler will automatically generate ==
, !=
, <
, <=
, >
and >=
operators and code for them:
struct Point {
int x;
int y;
int z;
auto operator<=>(const Point&) const = default;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With