There's two (or really 3) things about structure packing/padding.
By default, members are aligned based on their size, so 64bit values are 8 byte aligned, 32bit values are 4 byte aligned, and so on. Padding is introduced only to achieve proper alignment of members.
For the end of the structure, it will be padded out based on the largest sized member. This is done so that an array of the struct will have consistent alignment.
If packing is enabled, then no padding is introduced anywhere.
I'm not aware of any compilers that have a type smaller than a byte. Bitfields are a special case, but in reality they are stored in a type that is at least a byte, and packing won't reduce unused bits in the bitfield. Padding/packing still applies to the types used for the bitfield.
struct foo
{
int x : 1;
};
This still takes up the space of an int.
struct bar
{
int x : 1;
int y : 1;
};
This still takes up the space of an int (just one).
struct foobar
{
int x : 1;
char y : 1;
};
This takes up the space of an int PLUS a char, because changing the type of a bitfield starts a new one.
Note this would also likely be padded out at the end of the struct to a multiple of size int (i.e. 3 bytes in this case).
There's two (or really 3) things about structure packing/padding.
By default, members are aligned based on their size, so 64bit values are 8 byte aligned, 32bit values are 4 byte aligned, and so on. Padding is introduced only to achieve proper alignment of members.
Actually not quite true. For example, when compiling for 32bit x86 Linux, unit64_t is 4 byte aligned. Yes, for very stupid reasons, this not just depends on CPU architecture, but also on operating system.
Yeah, there are exceptions, especially for 64bit Smile where people made bad choices to ease transition or for compatibility.
I assume the ABIs for that were decided before x64 even was a thing... What is uttely craptastic is the inconsistent size of the long type. Technically, this affects all integer types, but almost all (angry look at cc65) compilers have settled on char/short/int being 8/16/32 bit. long is sometimes 32, sometimes 64, who knows?
...
Which is why IMO the only integer types one should use are int (because it is somewhat ingrained in some parts of the language. Just try not to depend on it being more than 16 bit too often.) and the non-ludicrous types from stdint.h, ideally typedef'd to less verbose names (and of course char when you're actually dealing with characters)
For propeller-related code, I generally use these (the "vm" prefix being an artifact of where it was copy-pasted from that kinda stuck):
I'm struggling to find a way to put a large image of the font rom from the prop 1 into a flexbasic program. Using data statements and then reading into an array seems inefficient as, as far as I can tell the image is duplicated, once in data statements and then when parcelling into an array. In propbasic you just assign a label and then data statements and read directly from that, indexed from the label, but I can't see a similar way to do it in flexbasic.
I know there MUST be a way but I can't just figure it out.
Oh and by the way- hex variables don't work in data statements when using the $prefix but 0x works fine.
Found it from a an old post buried in the fastspin forum.
dim shared as ushort font(8000) = {0x0001,0x0001,0x0003,_
0x0004,0x0005,0x0006,0x0007,0x0008,0x000a,0x000b,0x000c,0x000e,_
0x000f,0x0E38,0x0E38,0x0E38,0x3FFE,0x3FFE,0x3FFE,0x0E38,0x0E38 }
There seems to be an issue when assigning a structure value to a variable of the same name, not earlier defined...
This gives an error:
//int x, y;
int x = MouseStatus.x - (oLeft << 4);
int y = MouseStatus.y - (oTop << 4);
But, if I do the declaration of x and y in the line before, it works.
Error message looks like this:
1>Forms.h:1174: error: unknown identifier x_0122 in class __struct__anon_18bd68b200000110
1>Forms.h:1174: error: x_0122 is not a member of __struct__anon_18bd68b200000110
1>Forms.h:1175: error: unknown identifier y_0123 in class __struct__anon_18bd68b200000110
1>Forms.h:1175: error: y_0123 is not a member of __struct__anon_18bd68b200000110
1>Forms.h:1174: error: unknown identifier x_0122 in class __struct__anon_18bd68b200000110
1>Forms.h:1174: error: x_0122 is not a member of __struct__anon_18bd68b200000110
1>Forms.h:1175: error: unknown identifier y_0123 in class __struct__anon_18bd68b200000110
1>Forms.h:1175: error: y_0123 is not a member of __struct__anon_18bd68b200000110
I'm struggling to find a way to put a large image of the font rom from the prop 1 into a flexbasic program. Using data statements and then reading into an array seems inefficient as, as far as I can tell the image is duplicated, once in data statements and then when parcelling into an array. In propbasic you just assign a label and then data statements and read directly from that, indexed from the label, but I can't see a similar way to do it in flexbasic.
flexbasic allows assembly (like Spin) so you can use the FILE statement inside that. The only slightly tricky bit is that the type of the labels inside the assembly might not come out the way you want, but the easy work-around for that is to explicitly declare a pointer variable with the correct type, e.g.:
asm shared
mydata
file "font.bin" ' include the font data
end asm
dim fontptr as ubyte ptr
fontptr = @mydata ' mydata is the label inside the asm shared
' now access the data via fontptr, e.g. fontptr[0] is the first byte, fontptr[1] the second, etc.
@ersmith
Thanks. Actually, as I note two posts up I found an answer...
dim shared as ushort font(8000) = {0x0001,0x0001,0x0003,_
0x0004,0x0005,0x0006,0x0007,0x0008,0x000a,0x000b,0x000c,0x000e,_
0x000f,0x0E38,0x0E38,0x0E38,0x3FFE,0x3FFE,0x3FFE,0x0E38,0x0E38 }
and to read it out..
f=font(x)
This will do nicely for me, trying to avoid any of this new fangled stuff like 'pointers' 'any' 'class' and such.
Looking at the new Parallax website. I like it a lot. Impressive. Now a bit of nit picking:
In the Running Hello World and Blinking LED programs featured in Home>Propeller2>Get Started>FlexC the #include header files seem to be missing in the explanatory text.
There seems to be an issue when assigning a structure value to a variable of the same name, not earlier defined...
This gives an error:
//int x, y;
int x = MouseStatus.x - (oLeft << 4);
int y = MouseStatus.y - (oTop << 4);
But, if I do the declaration of x and y in the line before, it works.
Error message looks like this:
1>Forms.h:1174: error: unknown identifier x_0122 in class __struct__anon_18bd68b200000110
1>Forms.h:1174: error: x_0122 is not a member of __struct__anon_18bd68b200000110
1>Forms.h:1175: error: unknown identifier y_0123 in class __struct__anon_18bd68b200000110
1>Forms.h:1175: error: y_0123 is not a member of __struct__anon_18bd68b200000110
1>Forms.h:1174: error: unknown identifier x_0122 in class __struct__anon_18bd68b200000110
1>Forms.h:1174: error: x_0122 is not a member of __struct__anon_18bd68b200000110
1>Forms.h:1175: error: unknown identifier y_0123 in class __struct__anon_18bd68b200000110
1>Forms.h:1175: error: y_0123 is not a member of __struct__anon_18bd68b200000110
@Rayman, I can't seem to reproduce this. Do you have a complete example I could try? There's something context dependent (which is usually the case with these kinds of bugs).
Normally in C you would use octal or hex escape sequences within a string...
I think I'm figuring this out... I've learned that you can use multiple quotes and the compiler will concatenate them all. That helps a lot.
The hex escape sequence (for some unknown reason) doesn't stop after two characters. What a pain. But, can use two quotes to break out of it.
Still, I think the Spin2 way has some advantages here...
I've released flexprop 5.0.1 on my github page. There's no update for spin2cpp/flexspin: I think at this point I'm going to stop making separate binary releases for these, since they're bundled into flexprop.
I've released flexprop 5.0.1 on my github page. There's no update for spin2cpp/flexspin: I think at this point I'm going to stop making separate binary releases for these, since they're bundled into flexprop.
I've certainly been gone far too long. What is flexprop? I've been building spin2cpp on my own and using the resulting fastspin executable. Is that no longer an option? What is the command line compiler called these days?
Edit: Never mind. I see it's now called flexcc, a much better name.
FlexProp is what he renamed FlexGui to. Then there is FlexC, FlexSpin, FlexBASIC that are all compiled with spin2cpp variants (flexspin and flexcc). I think flexspin.exe and flexcc.exe are the same compiler, but flexcc has different message outputs (and maybe command line options?) to better work with IDEs/etc. that can talk to gcc/etc.
FlexProp is what he renamed FlexGui to. Then there is FlexC, FlexSpin, FlexBASIC that are all compiled with spin2cpp variants (flexspin and flexcc). I think flexspin.exe and flexcc.exe are the same compiler, but flexcc has different message outputs (and maybe command line options?) to better work with IDEs/etc. that can talk to gcc/etc.
Thanks! I've switched my makefile to use flexcc and all is good. Thanks to Eric for all of his work on the flex suite!
FlexProp is what he renamed FlexGui to. Then there is FlexC, FlexSpin, FlexBASIC that are all compiled with spin2cpp variants (flexspin and flexcc). I think flexspin.exe and flexcc.exe are the same compiler, but flexcc has different message outputs (and maybe command line options?) to better work with IDEs/etc. that can talk to gcc/etc.
Yes, the command line options for flexcc and flexspin are different -- flexcc takes gcc like arguments, and flexspin takes openspin like arguments. Otherwise they're the same compiler.
Comments
By default, members are aligned based on their size, so 64bit values are 8 byte aligned, 32bit values are 4 byte aligned, and so on. Padding is introduced only to achieve proper alignment of members.
For the end of the structure, it will be padded out based on the largest sized member. This is done so that an array of the struct will have consistent alignment.
If packing is enabled, then no padding is introduced anywhere.
I'm not aware of any compilers that have a type smaller than a byte. Bitfields are a special case, but in reality they are stored in a type that is at least a byte, and packing won't reduce unused bits in the bitfield. Padding/packing still applies to the types used for the bitfield. This still takes up the space of an int. This still takes up the space of an int (just one). This takes up the space of an int PLUS a char, because changing the type of a bitfield starts a new one.
Note this would also likely be padded out at the end of the struct to a multiple of size int (i.e. 3 bytes in this case).
Actually not quite true. For example, when compiling for 32bit x86 Linux, unit64_t is 4 byte aligned. Yes, for very stupid reasons, this not just depends on CPU architecture, but also on operating system.
...
Which is why IMO the only integer types one should use are int (because it is somewhat ingrained in some parts of the language. Just try not to depend on it being more than 16 bit too often.) and the non-ludicrous types from stdint.h, ideally typedef'd to less verbose names (and of course char when you're actually dealing with characters)
For propeller-related code, I generally use these (the "vm" prefix being an artifact of where it was copy-pasted from that kinda stuck):
I'm struggling to find a way to put a large image of the font rom from the prop 1 into a flexbasic program. Using data statements and then reading into an array seems inefficient as, as far as I can tell the image is duplicated, once in data statements and then when parcelling into an array. In propbasic you just assign a label and then data statements and read directly from that, indexed from the label, but I can't see a similar way to do it in flexbasic.
I know there MUST be a way but I can't just figure it out.
Oh and by the way- hex variables don't work in data statements when using the $prefix but 0x works fine.
Dave
Mike
@iseries I wouldn't mind betting that could work- flexbasic is rather 'C' like!, will give it a try.
Thanks
Dave
The docs say you can include a .Spin2 file in your BASIC program like this:
I think I would do this so as to include the font as a binary file.
Found it from a an old post buried in the fastspin forum.
Onwards and upwards.
Dave
This gives an error:
But, if I do the declaration of x and y in the line before, it works.
Error message looks like this:
flexbasic allows assembly (like Spin) so you can use the FILE statement inside that. The only slightly tricky bit is that the type of the labels inside the assembly might not come out the way you want, but the easy work-around for that is to explicitly declare a pointer variable with the correct type, e.g.:
Update: It works!
I actually just happened to need this!
@ersmith
Thanks. Actually, as I note two posts up I found an answer...
and to read it out..
This will do nicely for me, trying to avoid any of this new fangled stuff like 'pointers' 'any' 'class' and such.
Dave
In the Running Hello World and Blinking LED programs featured in Home>Propeller2>Get Started>FlexC the #include header files seem to be missing in the explanatory text.
The FlexC support looks almost official... Nice to see...
@Rayman, I can't seem to reproduce this. Do you have a complete example I could try? There's something context dependent (which is usually the case with these kinds of bugs).
Thanks, @Rayman. I think I've found the problem and it'll be fixed in the next release.
Just out of curiosity...
In addition to "File", Spin2 also has some advantages declaring string data...
To convert this: to C, looks like this:
Is there a better way to do this in FlexC?
But anything you can put in a Spin DAT section can go in a C __pasm, so you could use byte statements instead just like you would in Spin.
I think I'm figuring this out... I've learned that you can use multiple quotes and the compiler will concatenate them all. That helps a lot.
The hex escape sequence (for some unknown reason) doesn't stop after two characters. What a pain. But, can use two quotes to break out of it.
Still, I think the Spin2 way has some advantages here...
It was supposed to work, but there was a bug in the handling of strings inside __pasm. That should be fixed now in 5.0.1.
Edit: Never mind. I see it's now called flexcc, a much better name.
When I try to compile the versions I have I get this kind of warning message: Did something change with FatFs support?