Local variables using other structs and being unable to access type not in memory #2797
Replies: 3 comments 12 replies
|
The problem is probably with the assignment of structures which can fail if the structures are complex. The thing is that you rarely need to assign structs by value when you can just create pointers to reference them instead, so maybe try NestedEntry entry @ addressof( parent.parent.archive.entries[current_index]); // cause of issue as it tries to re-process NestedEntry |
|
you have MyArchive.count entries and each has MyArchive.count attributes. So you are creating count squared references to structures of which there are only Nested_Entries.count of them. How does that work? |
Actually the suggestion of adding count to Attributes was a bad one. It is bad because it is based on a bad format spec design. There should be only one source for the number of elements in the array that is to be referenced. Having count in both MyArchive and NestedArchive can lead to the creation of null references so the correct suggestion should have been to make NestedEntry use parent.parent.count. The following code follows that suggestion and worked on the sample input provided import std.core;
// I tested this pattern with the following hex values
#pragma example 00 02 10 00 74 65 73 74 00 6E 61 6D 65 00 00 00 02 61 62 03 61 62 63 00
// this pattern is dynamic and its size depends on where it is placed.
// I suspect it cannot be used for local variable assignments
// because it needs to be instantiated before assignment.
struct NestedEntry {
u32 current_index = std::core::array_index();
u8 length;
char name[length];
if (current_index == parent.parent.count - 1) {
// if NestedArchive.count and MyArchive.count are different the references would break
// so NestedArchive should not define count and use its parent's instead which forces
// NestedEntry to use parent.parent. Therefore Entries is the only struct that needs
// to define count but it already uses it so it makes sense to add it there.
u8 terminal_byte;
}
};
struct NestedArchive {
// count shouldn't be defined here and doesn't need to be.
NestedEntry entries[parent.count];
};
struct Attribute {
// this now works as expected. I'm not certain but the error seen when using =
// could be created if pattern needs to be instantiated prior to the assignment
// due to its dynamic nature.
NestedEntry entry @ addressof(parent.parent.archive.entries[std::core::array_index()]);
};
struct Entry {
char name[];
// this is the only place count needs to be added but seems like it can use it too
u8 count = parent.count;
Attribute attributes[count];
};
struct MyArchive {
// Broadly speaking, it looks like this.
u8 version;
u8 count;
u16 data_offset;
NestedArchive archive @(addressof(this) + data_offset);
// having count entries seems wrong too. there is only one array of size count
// already defined in Entry
Entry entries[count];
};
MyArchive archive @ 0x0; |



Uh oh!
There was an error while loading. Please reload this page.
So, I'm experiencing somewhat confusing. The premise is this:
if field
ais resolved before fieldb, you would think that you can reference the children of fieldainbwithout issue. However, I'm experiencing issues, but only with my real data.In the test I made, thinking that maybe it was a bug, I did NOT experience an error.
In this, it just works,
attributes, which is referenced AFTERchild, properly is able to accesschild'sentries.However, when attempting to do so with my real data, I run into:
E: runtime error: Cannot access data of type that hasn't been placed in memory.Here is a more similar example to what I actually have which DOES reproduce the error, but I don't actually see how it differs from the one that works, nor why an error is occurring.
Have a file that starts with 16 bytes, with the first 3 bytes as
01 02 0A.All reactions