Incorrect treatment of captured-type casts/sizeof in type views
Hi there,
I want to create a view for a custom C++ array type and I believe I'd need to cast in the view syntax, which doesn't seem possible, or maybe I'm just missing how it works.
The array type is defined roughly like this (simplified here for demonstration purposes), in that it is templated, but always stores data in the same underlying type; all type conversion is done in the interface:
template <typename T>
class TArray
{
class TData
{
int mSize;
int8_t* mData;
};
TData* mArrayData;
int Size() { return mArrayData->mSize / sizeof(T); }
T* Data() { return reinterpret_cast<T>(mArrayData->mData); }
};
Now to create a view for this, I went with
TArray<?> -> array($.mArrayData.mData, $.mArrayData.mSize)
but of course this gives me an array in terms of int8_t, not T. I think what I would actually need is something like
TArray<?(T)> -> array((T)$.mArrayData.mData, $.mArrayData.mSize / sizeof(T))
The capturing syntax with the ?(T) is something I found in another Github issue discussion, but it doesn't seem to work, so I tried a specialied type instead:
TArray<wchar_t> -> array((wchar_t)$.mArrayData.mData, $.mArrayData.mSize / sizeof(wchar_t))
and then I get an error Cannot convert this type when trying to view a variable with this type.
Is this supposed to work and I'm just missing the correct syntax? Or is it just something that's not possible or not implemented yet?
TArray<?{T}> -> array(cast(T*)$.mArrayData.mData, $.mArrayData.mSize / sizeof(T))
First point mentioned here: https://github.com/EpicGamesExt/raddebugger/releases/tag/v0.9.20-alpha
I think c-style casts have some ambiguity while parsing expression for type views, so there is cast(T*) for that.
Ah, thanks, I missed the kind of brackets to use for the type capture.
Unfortunately, the cast(T*) doesn't seem to help. I still get the same Cannot convert this type error. I wonder if it's something about the nesting of the members that I need to disambiguate, but even a set of additional parentheses like TArray<?{T}> -> array(cast(T*)($.mArrayData.mData), $.mArrayData.mSize / sizeof(T)) doesn't help.
without sizeof(T) seems to work fine I think:
But doing sizeof(T) from within array view rule seems to be broken I guess.
sizeof(T) itself is working fine though.
Thanks for helping to debug this. Yeah, in the minimal example I sent, the sizeof in combination with the cast does indeed seem to be the problem.
I was curious why in the actual code that I adapted the minimal example from, the cast alone was still problematic, so I made another not-quite-so-minimal example that includes our weird way of allocating and referring to the allocated memory and with this, I can demonstrate the cast alone being a problem:
#include <vector>
template <typename T> struct TArray {
struct TData {
TData(int size) : mSize(size) {}
int mSize;
int8_t mData[1];
};
TData *mArrayData;
void SetSize(int size) {
const auto mem = malloc(offsetof(TData, mData) + size * sizeof(T));
mArrayData = new (mem) TData(size * sizeof(T));
}
int Size() { return mArrayData->mSize / sizeof(T); }
T *Data() { return reinterpret_cast<T *>(mArrayData->mData); }
};
int main() {
std::vector<wchar_t> expected{L'W', L'o', L'r', L'd'};
TArray<wchar_t> array;
array.SetSize(expected.size());
memcpy(array.Data(), expected.data(), expected.size() * sizeof(wchar_t));
//
}
Without the cast, it works (although not showing the expected type, of course):
With the cast, I get the "Cannot convert this type" error:
This code is maybe a bit unorthodox, but I'd expect the cast to just work also in this case, because it's just a cast after all that should allow changing the interpretation of things.