0

I don't know it that's possible, probably not - but maybe

What I'm trying to achieve is like the following, just for n sized chars array:

*(__int64*)(address) = 0x1337;

this works just fine for type __int64 or __int32 or float and many more, what I want to do is

*(char[8]*)(address) = [0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
Daniel Cohen
  • 163
  • 1
  • 7
  • Does this do what you want? https://stackoverflow.com/a/35745703/2602718 – scohe001 Sep 21 '20 at 14:26
  • it does, but I wanted to achieve this with casting and not `memcpy` – Daniel Cohen Sep 21 '20 at 14:28
  • 3
    Casting will be the path to **undefined behavior**; `std::memcpy` is the supported way to do this kind of shenanigans. – Eljay Sep 21 '20 at 14:32
  • 1
    To cast to a pointer to an array, you can use `(char (*)[8])address`. But don’t. – prl Sep 21 '20 at 14:38
  • @prl this doesnt work at c17 at least – Daniel Cohen Sep 21 '20 at 14:41
  • Yes, you can cast to pointer-to-array, but you can only *initialize* a newly declared object, not *assign* a whole array object with the `=` operator. [How to cast simple pointer to a multidimensional-array of fixed size?](https://stackoverflow.com/q/11869056). If you want to assign and don't care about violating strict-aliasing undefined behaviour, you could cast to a pointer to a struct containing an array. Also remember that the syntax for a literal of that type will also involve a cast, and `{{ 1, 2, 3 }}` curly braces not square brackets. (2 levels for an array inside a struct). – Peter Cordes Sep 21 '20 at 14:41
  • With stack allocated temporary arrays, the compiler should be able to optimize it anyway. Otherwise I don't see anything else to worry about. – user202729 Sep 21 '20 at 14:45
  • 1
    Can you clarify what language you want to know about? This is tagged both [tag:c++] and [tag:assembly] even though it appears to not have anything to do with assembly language, and in your comment you mention C which is yet a third language. – Nate Eldredge Sep 21 '20 at 23:18

1 Answers1

2

Is it possible to cast to fixed sized array in cpp?

No, it is not possible to cast to an array type in C++. But you can cast to a pointer to array for example, which I'm guessing may be what you're trying to do.

*(char[8]*)(address)

I suppose that you're trying to cast address into a pointer to an array. That is not the correct syntax for pointer to array. This is correct: *(char(*)[8])(address)

Other problem is that arrays are not assignable. What you can do instead is assign each element of the array. There are standard algorithms to do loops like this. In this case, a simple solution is to declare an array with those elements, and copy from that array to the one pointed by address. Example:

char* ptr = *static_cast<char(*)[8]>(address);
constexpr std::array data{0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
std::copy(std::begin(data), std::end(data), ptr);

A way to assign arrays is to wrap them inside a class, and use the assignment operator of that class. In fact, std::array template used in the above example is exactly such wrapper. If you used that type for your original array, then you could simply do:

std::array<char, 8> array;
void* address = &array; // imagine that for some reason you are forced to use void*

*static_cast<std::array<char, 8>*>(address)
    = {0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

P.S. Avoid C-style casts.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • `data` can be `const` or `static const`, which may help the compiler be less dumb and actually do an immediate store. Although hopefully compilers would figure it out with optimization enabled. – Peter Cordes Sep 21 '20 at 14:46
  • @PeterCordes Better yet: constexpr – eerorika Sep 21 '20 at 14:47
  • You say `*(char(*)[8])(address) = ....` "is correct". But array assignment isn't supported, only initialization. So the `=` part of that expression is actually not correct. If you want to violate strict-aliasing and actually assign, you need a `struct { char a[8]; };` and need to cast or something on the RHS to create an appropriate anonymous object of the right type. (In C you can do that with a cast). Or perhaps cast to a reference to `std::array`, if that works? – Peter Cordes Sep 21 '20 at 14:50
  • @DanielCohen This is C++, not C – eerorika Sep 21 '20 at 15:28
  • ya my bad I meant c++17 – Daniel Cohen Sep 21 '20 at 15:47