Page 1 of 1
Number indexing of structs
Posted: 29 Mar 2012, 17:45
by mattallen37
Is there a way to number index the elements(?) of a struct? I like being able to use multiple types of variables (e.g. strings and bytes), but is there a way to address a specific element, numerically?
If you put one struct in another, can you number access both layers as a more dim array?
Re: Number indexing of structs
Posted: 30 Mar 2012, 02:39
by afanofosc
You cannot do that at the moment. The problem is that would require firmware support for a runtime offset to a variable number.
John Hansen
Re: Number indexing of structs
Posted: 30 Mar 2012, 03:23
by mattallen37
Alright, thanks.
Re: Number indexing of structs
Posted: 30 Mar 2012, 10:41
by ricardocrl
But does this make sense, conceptually? I mean, in C or C-like languages at least, I don't remember to have this possibility, if I understood what mattallen said.
You mean using the elements of a structure as if they were in an array?
Re: Number indexing of structs
Posted: 30 Mar 2012, 15:29
by HaWe
in C you could use a pointer (to the address of the first element of a struct) and inc the pointer value by the value of the size of the following struct element.
Thats not exactly what matt wants, but its sort of "counting forward" the struct elements from one to the next.
Re: Number indexing of structs
Posted: 21 Apr 2012, 20:39
by muntoo
For example, a
simple implementation (bad coding style, and probably buggy, but I don't care) in C++ would be:
Code: Select all
struct C
{
int a, b, c;
size_t s = {0, sizeof(a), sizeof(b), sizeof(c)};
void* index(int i)
{
void* r = this;
while(i--)
r += s[i];
return r;
}
};
Not sure about more complex and flexible implementations; you'll have ask someone else (if you're interested, try on
Stack Overflow).
Re: Number indexing of structs
Posted: 22 Apr 2012, 11:08
by spillerrec
In C++ you can even overload the [] operator so you actually could call C[1] and get the "a" member.
Code: Select all
#include <cstring>
struct C{
private:
static const size_t s[];
public:
int a,b,c;
void* operator[]( int i ){ return this + s[i]; }
} temp;
const size_t C::s[] = { (unsigned)&temp.a - (unsigned)&temp, (unsigned)&temp.b - (unsigned)&temp, (unsigned)&temp.c - (unsigned)&temp };
#include <iostream>
int main(){
C c;
*(int*)c[0] = 5;
*(int*)c[1] = 6;
*(int*)c[2] = 2;
std::cout << "a: " << *(int*)c[0] << "\n";
std::cout << "b: " << *(int*)c[1] << "\n";
std::cout << "c: " << *(int*)c[2] << "\n";
}
Notice the temp variable which is needed because the struct might be padded when it have members of different types. In those cases a simple sizeof implementation would fail. (The pointer arithmetics might also fail on 64-bit, not sure and too lazy to fix or look it up.)
Casting a void pointer is also dangerous, so making a proper implementation would require you to make a wrapper class around the pointer which also stores type information so you can safely cast it. (The firmware doesn't have anything similar to a void pointer so you can't do any of this when the members varies. A variable which could hold multiple types would be rather useful though when we don't have overloading.)
I really want to know what you need this kind of behavior for, as I can only see disadvantages and no use-cases...