#include <cstddef>
#include <iostream>

// In C we need a length in bytes to check for equality
void compareObject(void *a, void *b, size_t len) {
    if (a == b)
        std::cout << "Same address" << std::endl;

    // Being explicit about pointer type allows pointer arithmetic
    unsigned char *i1 = (unsigned char *)a;
    unsigned char *i2 = (unsigned char *)b;

    for (size_t i = 0; i < len; i++) {
        if (i1[i] != i2[i]) {
            std::cout << "Different value" << std::endl;
            return;
        }
    }

    std::cout << "Same value" << std::endl;
}

template <typename T> void cmp(T &a, T &b) {
    if (&a == &b)
        std::cout << "Same object" << std::endl;

    if (a == b)
        std::cout << "Same value" << std::endl;
    else
        std::cout << "Different value" << std::endl;
}

int main() {
    int a = 10, b = 10, c = 12;

    std::cout << "Checking template version" << std::endl;

    cmp(a, b);
    cmp(a, c);

    std::cout << "Checking C version" << std::endl;

    compareObject(&a, &b, sizeof(int));
    compareObject(&a, &c, sizeof(int));
}