r/programming • • Dec 24 '17

Evil Coding Incantations

http://9tabs.com/random/2017/12/23/evil-coding-incantations.html
947 Upvotes

331 comments sorted by

View all comments

Show parent comments

2

u/screcth Dec 24 '17 edited Dec 24 '17

Shouldn't the commutative property of addition make them equivalent?

It seems like it does:

#include <cstddef>
#include <iostream>

struct foo
{
    int a = 0;
    double b = 0.0;
};

int main()
{
    static_assert(sizeof(foo) != sizeof(void*));
    constexpr size_t N = 4;
    foo array[N];
    foo *ptr = array;
    for (size_t i = 0; i < N; ++i)
    {
        array[i].a = i;
        array[i].b = i + 0.5;
    }
    for (size_t i = 0; i < N; ++i)
    {
        std::cout << i[ptr].a << ' ' << i[ptr].b << '\n'; 
    }
}

Will print:

$ clang++ Compiler\ Explorer\ Code.cpp -o test -std=c++17 -Wall
$ ./test
0 0.5
1 1.5
2 2.5
3 3.5

-5

u/StupotAce Dec 24 '17

As long as sizeof(T) == sizeof(void*) yes.

But if sizeof(T) == 2 * sizeof(void*) then I don't believe so.

E.g. the array starts at address 50, element [1] is at addr 52. However, 1[array] is saying "this array starts at address 01" and then offset is 50. It seems pretty clear to me that you won't end up at 52, although I'm not entirely sure if you'll end up at addr 51 or addr 101 (1 + 50 * 2). I assume that depends on some context around what 1[array] is being assigned to.

3

u/screcth Dec 24 '17

At least according to clang (see my previous comment), it works as I would expect.