0

I have a class that I use to reinterpret data, but the underlying data is of the same type and yet doing this seems to violate strict aliasing. I would like to be able to reinterpret_cast to choose how to interpret the data. Here's an example:

#include <iostream>
#include <cstdlib>

template <int M>
struct mul {
    int i[10];
    void multiply(int idx) {
        std::cout << i[idx] * M << std::endl;
    }
};
void f(mul<1> &s, mul<2> &t) { int i = s.i[0]; t.i[0]++; if (s.i[0] == i) std::abort(); }
int main() {
    mul<1> s;
    f(s, reinterpret_cast<mul<2> &>(s)); 
}

The abort shows that this violates strict aliasing even though the basic type is int*. Is there a reason why this should violate strict aliasing? Is there another solution to this style problem - this is a simplified case, imagine a much more complex set of functions and reinterpretations of data using a reinterpret_cast.

I use these reinterpreted types for passing into templatized functions.

Command:

g++-8 -O3 -g test.cpp -o test

Output:

Abort trap: 6

g++-8 --version:

g++-8 (Homebrew GCC HEAD-252870) 8.0.0 20170916 (experimental) Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

nachum
  • 567
  • 9
  • 17
  • Your program has undefined behavior since you are using `mul::i` without initializing it. – R Sahu Jan 12 '18 at 23:34
  • 1
    What are you trying to do here? Seems like it's got XY problem written all over it. – Mysticial Jan 12 '18 at 23:37
  • The goal is view int[10] in different ways. For example, I can cast as a mul<10> to see each entry multiplied by 10. The f() is meant to demonstrate that I've violated strict aliasing. I am wondering if there is a way to accomplish this without violating strict aliasing. – nachum Jan 12 '18 at 23:44
  • 1
    Why do you think it *shouldn't* violate strict aliasing? You have two references to the same struct, and they have different types. The fact that the members have the same type is irrelevant, you're aliasing the struct. – Barmar Jan 13 '18 at 00:31
  • I agree with you. I was hoping that my goal was clear and that perhaps there is a nice way to get this working without violating strict aliasing. Any thoughts? – nachum Jan 13 '18 at 00:35
  • _"Where strict aliasing prohibits examining the same memory as values of two different types, std::memcpy may be used to convert the values."_: http://en.cppreference.com/w/cpp/string/byte/memcpy – Richard Critten Jan 13 '18 at 00:48
  • Why are you building a function into the data? The `M` is just a function parameter – Passer By Jan 13 '18 at 08:46
  • Imagine functionality that reorders or reinterprets indexing - ie operator[] now produces different results based on M. I can then use a reinterpret to virtually remove an index, or reorder the contents of an array without copying the array. When used with templated functions, the function would not need to know the type of the array, it would just call operator[] and get the correct location based on M. That is the exercise here. – nachum Jan 16 '18 at 18:28

0 Answers0