Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Augments and variable length data forms

146 views
Skip to first unread message

rick.c...@gmail.com

unread,
Jun 12, 2020, 11:10:16 PM6/12/20
to
Chris Thomasson, I wanted to get your input. Maybe there's already
a syntax to handle these cases in C or C++.

I have a class or struct defined at some point like this:

struct SWhatever
{
void* data; // Reference to user-data
};

In some module of my application, I know that the data member
will be some other structure and no longer needs to be referenced
as void*. I can now reference it directly by the type that's used
in that module.

What syntax could I create to augment that member with later known
types? I am considering this syntax:

struct SMyWhatever : SWhatever
{
augment SList* data; // Changes void* to SList*
};

-----
And in another case, I have a variable length structure whose
length is determined by parent / discriminating members higher
up, like this:

struct SVarData
{
int length;
char data[1];
};

The actual length of the data member is set by the runtime-set
length property. And if the length property is 0, there is no
data member present in that instance.

I have in mind to use this syntax:

struct SVarData
{
int length;
var_char data[0..length];
};

It tells the compiler that the member will exist between 0 bytes
(not available), or up to length bytes (contextual at each runtime
instance).

In and of itself itwould not be useful, unless you recognize its
use in variable length structures like this:

struct SMultiVarData
{
int firstNameLength;
var_char firstName[0..firstNameLength];

int lastNameLength;
var_char lastName[0..lastNameLength];
};

In this case, using &x.lastName would compute properly given the
variable length nature of the flexible structure. The compiler
would inject code to compute properly based on the runtime obser-
vation of the dynamics of the particular instance.

It would allow flexible data formats to be used in a rigid and
fixed manner by definition, yet to access each member in the
flexible format it requires based on runtime dynamics. The same
would work for struct or class, but is more easily visualized in
example using the struct form above.

What do you think?

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 13, 2020, 4:58:52 AM6/13/20
to
And Satan invented fossils, yes?

/Flibble

--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin

“You won’t burn in hell. But be nice anyway.” – Ricky Gervais

“I see Atheists are fighting and killing each other again, over who doesn’t believe in any God the most. Oh, no..wait.. that never happens.” – Ricky Gervais

"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say."

Ben Bacarisse

unread,
Jun 13, 2020, 6:11:17 AM6/13/20
to
rick.c...@gmail.com writes:

> Chris Thomasson, I wanted to get your input.

You should consider using email. This is a group.

--
Ben.

Bart

unread,
Jun 13, 2020, 7:02:02 AM6/13/20
to
On 13/06/2020 04:10, rick.c...@gmail.com wrote:

> In and of itself itwould not be useful, unless you recognize its
> use in variable length structures like this:
>
> struct SMultiVarData
> {
> int firstNameLength;
> var_char firstName[0..firstNameLength];
>
> int lastNameLength;
> var_char lastName[0..lastNameLength];
> };
>
> In this case, using &x.lastName would compute properly given the
> variable length nature of the flexible structure. The compiler
> would inject code to compute properly based on the runtime obser-
> vation of the dynamics of the particular instance.

This for a new language? There are a few other approaches that might be
better.

But first, what exactly is the structure above - is the char data held
directly inside the struct? That's going to be awkward where you have
two of them.

How does it work exactly: do first/lastNameLength need to be determined
at the same time, and struct size calculated for both (sizeof(int)*2 +
firstlength+lastlength, +2 if zero-terminated), and then there are
fixed? How do the lengths get into the struct? What happens when you
pass a var_char to a function, does it somehow include its length, or do
you need the length passed explicitly?

Also, how does an access such as X.lastNameLength or X.lastname know the
offsets of those members, if they will depend on the X.firstNameLength?

If you say the compiler will sort it out, then I can gave a dozen
examples where it will have its work cut out to determine not only how
to do something, but what it even means.

I mentioned other ways, but since this is C++, why not just use its
'string' type? It includes its length, the two strings can be created at
different times, and there's no extra housekeeping for the lengths. But
the string data will be on the heap.

If it's necessary for the string data to be part of the struct, how
important is it that the struct is the exact size of the combined
strings? Having a fixed capacity is much easier, if these names will be
of a limited length.

There are also schemes where you allocate a fixed size in-place string,
but provide a mechanism for longer strings too, which are stored
elsewhere via a pointer. (Something like this is done in COFF files'
symbol tables.)

> Chris Thomasson, I wanted to get your input.

I forgot this bit. Please ignore the above...

rick.c...@gmail.com

unread,
Jun 13, 2020, 7:27:30 AM6/13/20
to
I didn't only want Chris's input. But specifically I wanted his. Will
take anyone else's as well.

I apologize if that wasn't clear.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 13, 2020, 9:58:02 AM6/13/20
to
On Saturday, June 13, 2020 at 7:02:02 AM UTC-4, Bart wrote:
> On 13/06/2020 04:10, rick.c...@gmail.com wrote:
>
> > In and of itself itwould not be useful, unless you recognize its
> > use in variable length structures like this:
> >
> > struct SMultiVarData
> > {
> > int firstNameLength;
> > var_char firstName[0..firstNameLength];
> >
> > int lastNameLength;
> > var_char lastName[0..lastNameLength];
> > };
> >
> > In this case, using &x.lastName would compute properly given the
> > variable length nature of the flexible structure. The compiler
> > would inject code to compute properly based on the runtime obser-
> > vation of the dynamics of the particular instance.
>
> This for a new language?

It's a consideration. I've had half-a-dozen needs for it on this
project I'm working on. It's a rare data need, but it is what I
consider to be a fundamental data need, and therefore it's some-
thing I would seek to add to my toolset.

> But first, what exactly is the structure above - is the char data held
> directly inside the struct? That's going to be awkward where you have
> two of them.

Yes. In memory it would be [int][char data][int][char data] all
consecutive, but either [char data] may be missing if the associated
[int] is 0.

> How does it work exactly: do first/lastNameLength need to be determined
> at the same time, and struct size calculated for both (sizeof(int)*2 +
> firstlength+lastlength, +2 if zero-terminated)

sizeof(int) * 2 + firstNameLength + lastNameLength. No extra bytes
for NULL-termination. If they include NULLs, it will be stored in
the associated length values.

> and then there are
> fixed? How do the lengths get into the struct?

This struct would be to traverse pre-compiled data. It would sit
atop data that exists, and would all pointer math to work by navi-
gating across the variable width data items.

> What happens when you
> pass a var_char to a function, does it somehow include its length, or do
> you need the length passed explicitly?

Passing var_char would pass a pointer to the start of data. You
would have to pass the length if you wanted it, or if had something
like NULL termination it would be there that way.

> Also, how does an access such as X.lastNameLength or X.lastname know the
> offsets of those members, if they will depend on the X.firstNameLength?

I should've said &x->lastName, and not &x.lastName. In my language,
. and -> do the same thing.

This type of variable structure would be primarily for reading
existing data. So you set the pointer to some location, and it
then interprets what it's sitting on.

> If you say the compiler will sort it out, then I can gave a dozen
> examples where it will have its work cut out to determine not only how
> to do something, but what it even means.

I see it as a series of accessor functions which are called when
various members are referenced, the need of which is to access
their variable locations in memory.

I can see also a constructor form where you're building something,
but it would require the variable lengths to all be provided at
construction.

> > Chris Thomasson, I wanted to get your input.
> I forgot this bit. Please ignore the above...

I can see how it wasn't clear. I was specifically looking for some
feedback from Chris, but welcome anybody else's feedback as well.
Your feedback is always welcomed, Bart.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 13, 2020, 10:52:44 AM6/13/20
to
On Saturday, June 13, 2020 at 7:02:02 AM UTC-4, Bart wrote:
> How does it work exactly...

Think of it as a way to parse something like a JSON structure that
is always in a fixed format, but has variable length portions within.

Rather than use JSON and parse through its structure mechanically,
you have portions which allow you to navigate immediately:

length1
firstname

length2
lastname

length3
address

And you define it in a fixed manner, with a minimum var_char member
width of 0. If you always needed at least 5 bytes in there, then
you would define it as [5..len]:

struct SPacket
{
int flen;
var_char f[0..flen];

int llen;
var_char l[0..llen];

int alen;
var_char a[0..alen];
};

Now, you have a fixed structure you can use in your application to
access each member. When data comes in, it will be like this:

[4][Rick][6][Hodgin][10][Abc Street][4][Bart][7][Mancuso][10]
[Xyz Street][3][Ben][2][B.][17][10 Downing Street]

With each member being its type, so if int is 32-bits, it would be
in memory:

0x00 040000005269636b06000000486f6467696e ....Rick....Hodgin
0x12 00000a000000416263205374726565740000 ......Abc Street..
0x24 0400000042617274070000004d616e637573 ....Bart....Mancus
0x36 6f000a00000058797a205374726565740000 o.....Xyz Street..
0x48 0300000042656e0002000000422e00001100 ....Ben.....B.....
0x5A 0000313020446f776e696e67205374726565 ..10 Downing Stree
0x6C 74 t

But each pointer would start at the beginning of whatever data is
there, and in this example every structure would have at least 3
integers, but it may have more data interspersed.

The compiler would generate code to navigate each one by looking
at those variable portions, and allowing things like:

++x;
--x;
x += 5;
x -= 5;
&x->a;

It would be a way to rapidly traverse any data form, and have it
be in a fixed manner for communication, without the need for any
parsing.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 13, 2020, 10:56:32 AM6/13/20
to
On Saturday, June 13, 2020 at 10:52:44 AM UTC-4, rick....@gmail.com wrote:
> struct SPacket
> {
> int flen;
> var_char f[0..flen];
>
> int llen;
> var_char l[0..llen];
>
> int alen;
> var_char a[0..alen];
> };


I think it wouldn't need the "var_" part, but the [0..len] would
be enough to indicate it's a variable form:

struct SPacket
{
int flen;
char f[0..flen];

int llen;
char l[0..llen];

int alen;
char a[0..alen];
};

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 13, 2020, 10:57:55 AM6/13/20
to
LOL. So Satan invented fossils, yes?

rick.c...@gmail.com

unread,
Jun 13, 2020, 11:03:55 AM6/13/20
to
On Saturday, June 13, 2020 at 10:57:55 AM UTC-4, Mr Flibble wrote:
> LOL. So Satan invented fossils, yes?

I look at your creativity, ingenuity, obvious talent in design and
coding ... and then I look at your attitude and I'm saddened.

You're such a force, Leigh, such a presence, but all will be lost
because you're completely flippant about the truth. You think
you're being cute and funny and have no idea what's coming for you.

Such an unnecessary waste.

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 13, 2020, 11:16:40 AM6/13/20
to
And Satan invented fossils, yes?

Bart

unread,
Jun 13, 2020, 11:48:17 AM6/13/20
to
On 13/06/2020 15:52, rick.c...@gmail.com wrote:
Your example is of a packed file format (except with fixed 32-bit length
fields). But that's just it - it's a file format.

In memory, it would be expanded to a series of (int,char*) pairs (with
the string data either copied to the heap, or still in-situ inside a
copy of the file directly loaded to memory).

Actually, it doesn't match your struct at all, as it will have some
number N strings, not known until runtime (and then it could be
different if used for multiple input files within a loop).

Your struct will have a fixed number of strings.

What you haven't explained is how an instance of such a string comes
about. Say you define a 3-string struct:

typedef struct {
int a; char s[0..a]; // array bounds 0 .. a-1
int b; char t[0..b];
int c; char u[0..c];
} S3;

Now we need an instance of this struct. No point in doing this:

S3 x;

as it won't know any string sizes, and it can't be expand like that. It
would need to be:

S3* x;

So, assuming that string data is provided by the three lengths A, B, and
C, and the strings are in the char* values S, T and U, which must all be
known at the same time, how does x come into existence?

Doing it manually is going to be rather tedious:

x = malloc(3*sizeof(int) + A + B + C);

x.a = A;
memcpy(x.s, S, A);

x.b = B;
memcpy(x.t, T, B);

x.c = C;
memcpy(x.u, U, C);

Here, they have to be done in order; A is done first otherwise it will
not know the offsets needed to access x.b or x.t. Unless that is done
manually too:

*((int*)((char*)(&x+sizeof(int)+A)) = B;

But I'm guessing.


Scott Newman

unread,
Jun 13, 2020, 12:32:36 PM6/13/20
to
Do you like this ?

#include <cstddef>
#include <cassert>

template<typename T, std::size_t N>
struct Container;

template<typename T>
struct ContainerBase
{
T &operator []( std::size_t i );
private:
template<typename T, std::size_t N>
friend struct Container;
#if !defined(NDEBUG)
size_t n;
#endif
};

template<typename T, std::size_t N>
struct Container : public ContainerBase<T>
{
Container();
private:
friend class ContainerBase<T>;
T a[N];
};

template<typename T, std::size_t N>
inline
Container<T, N>::Container()
{
n = N;
}

template<typename T>
inline
T &ContainerBase<T>::operator []( std::size_t i )
{
assert(i < n);
return ((Container<T, 1> *)this)->a[i];
}

using namespace std;

int main()
{
Container<int, 3> ci3;
ci3[1] = 1;
}

rick.c...@gmail.com

unread,
Jun 13, 2020, 1:41:49 PM6/13/20
to
On Saturday, June 13, 2020 at 11:48:17 AM UTC-4, Bart wrote:
> On 13/06/2020 15:52, rick.c...@gmail.com wrote:
> > Now, you have a fixed structure you can use in your application to
> > access each member. When data comes in, it will be like this:
> >
> > [4][Rick][6][Hodgin][10][Abc Street][4][Bart][7][Mancuso][10]
> > [Xyz Street][3][Ben][2][B.][17][10 Downing Street]
> >
> > With each member being its type, so if int is 32-bits, it would be
> > in memory:
> >
> > 0x00 040000005269636b06000000486f6467696e ....Rick....Hodgin
> > 0x12 00000a000000416263205374726565740000 ......Abc Street..
> > 0x24 0400000042617274070000004d616e637573 ....Bart....Mancus
> > 0x36 6f000a00000058797a205374726565740000 o.....Xyz Street..
> > 0x48 0300000042656e0002000000422e00001100 ....Ben.....B.....
> > 0x5A 0000313020446f776e696e67205374726565 ..10 Downing Stree
> > 0x6C 74 t
>
> Your example is of a packed file format (except with fixed 32-bit length
> fields). But that's just it - it's a file format.
>
> In memory, it would be expanded to a series of (int,char*) pairs (with
> the string data either copied to the heap, or still in-situ inside a
> copy of the file directly loaded to memory).
>
> Actually, it doesn't match your struct at all, as it will have some
> number N strings, not known until runtime (and then it could be
> different if used for multiple input files within a loop).

You're correct. I didn't have it set to be a packed struct when I
created it for illustration purposes. But, it would be like the one
below:

0x00 040000005269636b06000000486f6467 ....Rick....Hodg
0x10 696e0a00000041626320537472656574 in....Abc Street
0x20 0400000042617274070000004d616e63 ....Bart....Manc
0x30 75736f0a00000058797a205374726565 uso....Xyz Stree
0x40 740300000042656e02000000422e1100 t....Ben....B...
0x50 0000313020446f776e696e6720537472 ..10 Downing Str
0x60 65657400000000000000000000000000 eet

In lines, like this:

....Rick....Hodgin....Abc Street
....Bart....Mancuso....Xyz Street
....Ben....B.....10 Downing Street

040000005269636b06000000486f6467696e0a00000041626320537472656574
0400000042617274070000004d616e6375736f0a00000058797a20537472656574
0300000042656e02000000422e11000000313020446f776e696e6720537472656574

With integers highlighted:

[04000000]5269636b[06000000]486f6467696e[0a000000]41626320537472656574
[04000000]42617274[07000000]4d616e6375736f[0a000000]58797a20537472656574
[03000000]42656e[02000000]422e[11000000]313020446f776e696e6720537472656574

The struct has a fixed layout, in that it's int+char, int+char,
int+char, but the locations of all except the first two are
variable.

> Your struct will have a fixed number of strings.
>
> What you haven't explained is how an instance of such a string comes
> about. Say you define a 3-string struct:
>
> typedef struct {
> int a; char s[0..a]; // array bounds 0 .. a-1
> int b; char t[0..b];
> int c; char u[0..c];
> } S3;
>
> Now we need an instance of this struct. No point in doing this:
>
> S3 x;

A syntax like this would work. It would yield a struct that would
allow you to populate into it based on its variable construction.

x = new S3(a, b, c);

> as it won't know any string sizes, and it can't be expand like that. It
> would need to be:
>
> S3* x;
>
> So, assuming that string data is provided by the three lengths A, B, and
> C, and the strings are in the char* values S, T and U, which must all be
> known at the same time, how does x come into existence?
>
> Doing it manually is going to be rather tedious:
>
> x = malloc(3*sizeof(int) + A + B + C);
>
> x.a = A;
> memcpy(x.s, S, A);
>
> x.b = B;
> memcpy(x.t, T, B);
>
> x.c = C;
> memcpy(x.u, U, C);
>
> Here, they have to be done in order; A is done first otherwise it will
> not know the offsets needed to access x.b or x.t. Unless that is done
> manually too:
>
> *((int*)((char*)(&x+sizeof(int)+A)) = B;
>
> But I'm guessing.

You'd use new() to handle it, but my primary reason for creating
this variable structure is for processing packed data. I want
the ability to do this:

S3* p = (S3*)some_ptr;

for (int i = 0; i < 10; ++i, ++p)
{
// Process p here
}

To navigate through variable data using simple logic. And, with
new(), to be able to create output data using the syntax as well.

It would be very handy for certain types of data. It would allow
you to include inline character data with lengths, and without
having to do any follow-up processing. You could save data that
way to disk, restore it, or transmit it from A to B over a net-
work, and it would be automatically parsed upon receipt. No extra
processing.

--
Rick C. Hodign

rick.c...@gmail.com

unread,
Jun 13, 2020, 1:46:51 PM6/13/20
to
On Saturday, June 13, 2020 at 12:32:36 PM UTC-4, Scott Newman wrote:
> Am 13.06.2020 um 05:10 schrieb rick.c...@gmail.com:
> > And in another case, I have a variable length structure whose
> > length is determined by parent / discriminating members higher
> > up, like this:
> >
> > struct SVarData
> > {
> > int length;
> > char data[1];
> > };
> >
> > The actual length of the data member is set by the runtime-set
> > length property. And if the length property is 0, there is no
> > data member present in that instance.
> >
> > I have in mind to use this syntax:
> >
> > struct SVarData
> > {
> > int length;
> > var_char data[0..length];
> > };
>
> Do you like this ?
> [snip]
> int main()
> {
> Container<int, 3> ci3;
> ci3[1] = 1;
> }


It's clever, but it's difficult to read and parse, and it would
be difficult to implement with an ad hoc structure. The examples
I've given thus far only have int+char[], int+char[], int+char[]
repeating. But in the real world, there would be other inter-
mittent members.

I'm hoping to add something that is easier to code, mentally
visualize, and is straight-forward enough to be useful in real
code.

--
Rick C. Hodgin

Scott Newman

unread,
Jun 13, 2020, 2:04:13 PM6/13/20
to
> I'm hoping to add something that is easier to code, mentally
> visualize, and is straight-forward enough to be useful in real
> code.

C++ isn't a language for easy solutions.

rick.c...@gmail.com

unread,
Jun 13, 2020, 2:18:21 PM6/13/20
to
True that! :-)

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 13, 2020, 2:29:00 PM6/13/20
to
On Saturday, June 13, 2020 at 10:56:32 AM UTC-4, rick....@gmail.com wrote:
> I think it wouldn't need the "var_" part, but the [0..len] would
> be enough to indicate it's a variable form:
>
> struct SPacket
> {
> int flen;
> char f[0..flen];
>
> int llen;
> char l[0..llen];
>
> int alen;
> char a[0..alen];
> };


Preliminary definition for variable length structs, and also for
discriminating structs, which allow for various types of data to
be processed using a single pointer. Class and struct member
function definitions can be added in each discr { } block, so
they are referenced when the pointer is pointing to that type
of data.

https://groups.google.com/d/msg/caliveprogramminglanguage/QN5-mCBlLzA/2NChpKISBwAJ

Will tweak it a little over time as needed.

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 13, 2020, 2:39:31 PM6/13/20
to
Oh look. Two trolls getting it on.

Bart

unread,
Jun 13, 2020, 5:03:27 PM6/13/20
to
None of these requires creating a new, highly specific language feature
implementation of which has considerable ramifications.

What's the problem with using this:

typedef struct {
int a; char* s;
int b; char* t;
int c; char* u;
} S3;

S3 x; // Now we CAN create it like this

x.a = A;
x.s = heapstr(S); // create copy of S on heap
// or just use x.s = S if appropriate

x.b = B;
x.t = heapstr(T);

x.c = C;
x.d = heapstr(U);

Advantages:

(1) This works NOW with no new features or new compiler with special
extensions for member access, sizeof() etc.

(2) The 3 strings inside x can be set up in any order

(3) They can be modified at any time, including making any string longer
or shorter.

(4) It's easy to create arrays of S3

(5) It's easy to embed S3 inside another struct, without making all
following members have dynamic offsets, or making the size of that
enclosing struct dynamic

(6) If set up using 'x.s = S' etc, this can point into the original
loaded file data, allowing certain in-place modifications

(7) S, T, U can all be slices of the same string data

(8) For very large strings, having them occupy separate heap areas puts
less pressure on memory compared with one allocation for all 3 strings

Although, I can't see what you can't just use a C++ 'string' type here.

Mr Flibble

unread,
Jun 13, 2020, 5:51:24 PM6/13/20
to
He is doing it because he believes it pleases his god. Such a waste of energy but delusions are such.

rick.c...@gmail.com

unread,
Jun 13, 2020, 6:09:31 PM6/13/20
to
On Saturday, June 13, 2020 at 5:03:27 PM UTC-4, Bart wrote:
> What's the problem with using this:
>
> typedef struct {
> int a; char* s;
> int b; char* t;
> int c; char* u;
> } S3;

Runtime parsing. Having the variable struct removes the need for
parsing. The data packet is ready to go as-is.

--
Rick C. Hodgin

Bart

unread,
Jun 13, 2020, 7:53:52 PM6/13/20
to
Even if some external data was a fixed number of three length+string
pairs, you would still to know the total size. That means traversing the
data.

If that total size of already known (eg. the size of a file containing
only those three), then accessing the 2nd and 3rd strings will still
need traversing the chain of lengths. Something that sounds like would
need to be done on every access, unless some auxilliary data structure
is set up.

And if that needs to be done anyway, then what is the point of the new
feature? Just use a function. Then maybe use C++ to be able to write x.u
instead of getstr(x,2).


Here's a mockup of such data, with the routines needed to extract
lengths and strings at random. Here, the only data structure needed is a
char array. I've used zero-terminated strings in the data, to simplify
printing them, but the data contained embedded strings anyway.

And I've used a sentinel to make this test simpler, since we don't have
a real context:

-----------------------------------------------

#include <stdio.h>
#include <stdint.h>
#include <string.h>

char data[]=
"\x06\x00\x00\x00" "Monday\x00"
"\x07\x00\x00\x00" "Tuesday\x00"
"\x09\x00\x00\x00" "Wednesday\x00"
"\x08\x00\x00\x00" "Thursday\x00"
"\x06\x00\x00\x00" "Friday\x00"
"\x08\x00\x00\x00" "Saturday\x00"
"\x06\x00\x00\x00" "Sunday\x00"
"\xFF\xFF\xFF\xFF";


int getstrn(char* data, int n, char** str) {
char* p=data;
int32_t length;

if (n<=0) return -1;

do {
memcpy(&length,p,4);
if (length==0xFFFFFFFF) return -1;
p += 4;
if (str) *str = p;
p += length+1;
} while (--n);

return length;
}

int countstrings(char* data){
int n=0, length;

while (1) {
length=getstrn(data,n+1,NULL);
if (length==-1) return n;
++n;
}
}

int getlength(char* data,int n) {
return getstrn(data,n,NULL);
}

char* getstring(char* data,int n) {
char* s;
getstrn(data,n,&s);
return s;
}

int main(void) {
char* s;
int nstrings, length;

nstrings = countstrings(data);

for (int i=1; i<=nstrings; ++i) {
length = getlength(data,i);
s = getstring(data,i);

printf("%d: %04d \"%s\"\n",i,length,s);
}
}

-----------------------------------------------

The output is:

1: 0006 "Monday"
2: 0007 "Tuesday"
3: 0009 "Wednesday"
4: 0008 "Thursday"
5: 0006 "Friday"
6: 0008 "Saturday"
7: 0006 "Sunday"

Note that real data could use a variable-length field for the string
length (some of my formats do). That can be accommodated here, but is
not practical using your scheme.

rick.c...@gmail.com

unread,
Jun 14, 2020, 7:59:27 AM6/14/20
to
On Saturday, June 13, 2020 at 7:53:52 PM UTC-4, Bart wrote:
> On 13/06/2020 23:09, rick.c...@gmail.com wrote:
> > On Saturday, June 13, 2020 at 5:03:27 PM UTC-4, Bart wrote:
> >> What's the problem with using this:
> >>
> >> typedef struct {
> >> int a; char* s;
> >> int b; char* t;
> >> int c; char* u;
> >> } S3;
> >
> > Runtime parsing. Having the variable struct removes the need for
> > parsing. The data packet is ready to go as-is.
> >
>
> Even if some external data was a fixed number of three length+string
> pairs, you would still to know the total size. That means traversing the
> data.

You wouldn't need to know the length in advance if it's a properly for-
matted string. You would traverse it until it terminates with a NULL
or some other stop code, such as all three a, b, c being 0.

But even so, when you read a network packet, you know the length. When
you open a file you can get the file length.

> If that total size of already known (eg. the size of a file containing
> only those three), then accessing the 2nd and 3rd strings will still
> need traversing the chain of lengths. Something that sounds like would
> need to be done on every access, unless some auxilliary data structure
> is set up.

That's where the compiler comes in. It adds that code automatically so
you don't have to do it. It allows you to use the data, and the compi-
ler handles the mechanics of access.

> And if that needs to be done anyway, then what is the point of the new
> feature? Just use a function. Then maybe use C++ to be able to write x.u
> instead of getstr(x,2).

It changes the data definition and logic portions of your source code
below to the example I write below.
1) Define the variable length structure. Clear. Concise:

struct SDay
{
int length;
char name[0..length];
};

2) Populate the data. Clear. Concise:

SDay data[] =
{
{ auto, "Sunday" },
{ auto, "Monday" },
{ auto, "Tuesday" },
{ auto, "Wednesday" },
{ auto, "Thursday" },
{ auto, "Friday" },
{ auto, "Saturday" }
};

3) Access the elements as they are, even though they're variable.
Clear. Concise:

auto p = data[0];

for (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i, ++p)
printf("%d: %04d \"data\", i, p->length, p->name);

The mechanics of calculating length is handled by the compiler at
compile-time. The mechanics of calculating the offset of p->name
is handled via an injected function or inline. The mechanics of
stepping forward for the ++p is handled via an injected function
or inline.

The compiler injects code to make your use of that feature easier.
And ultimately, it allows you to assemble data to transfer from
one source to another (inter-process communication, over the Inter-
net, saved to disk file and read later) without any parsing prior
to use. It allows immediate propagation and use of that data
without hindrance, but only the smallest performance hit by doing
the pointer calculations for member access, many of which could be
removed by placing any fixed members at the start of the struct or
class, and then only having variable length items at the end with
some optimization rearrangements.

It's a usable tool, Bart. If it existed natively in C or C++, it
would've already found wide use in normal data storage as it is a
consistent need for real-world data, and especially so in trans-
mitting data over a network.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 14, 2020, 8:01:34 AM6/14/20
to
On Sunday, June 14, 2020 at 7:59:27 AM UTC-4, rick....@gmail.com wrote:
> printf("%d: %04d \"data\", i, p->length, p->name);

:-) Me and my brain...

printf("%d: %04d \"%s\", i, p->length, p->name);

--
Rick C. Hodgin

Scott Newman

unread,
Jun 14, 2020, 8:02:34 AM6/14/20
to
If you're in a context where your authority isn't honored,
you're constantly trolling.

rick.c...@gmail.com

unread,
Jun 14, 2020, 8:20:33 AM6/14/20
to
On Sunday, June 14, 2020 at 8:02:34 AM UTC-4, Scott Newman wrote:
> If you're in a context where your authority isn't honored,
> you're constantly trolling.

Another term for that activity is "leading." It depends on the
validity of the underlying principles to determine which it is.

For example, compare your template construction idea to the code
I posted for Bart ... and decide for yourself.

--
Rick C. Hodgin

Bart

unread,
Jun 14, 2020, 10:50:54 AM6/14/20
to
You've changed the goalposts. First by treating each length/string in
isolation (like that, it reduces to ordinary C variable length structs,
where the only variable element is the last one, at a fixed offset).

Second by introducing another feature, which is that of arrays with
variable length elements, as I assume these are. If not, then you might
as well just use ordinary C++ features here:

#include <string>
#include <iostream>

using namespace std;

string ss [] = {"Monday","Tuesday","Wednesday","Thursday",
"Friday","Saturday","Sunday"};

int main(void) {
for (string s : ss)
cout<<" "<<s.size()<<" "<<s<<endl;
}

Which is clearer and more concise than your proposal.

What it doesn't have is a flat, inline replesentation of the data. But
if this is supposed to mirror what is going on in an external file
(perhaps via mmap), then I don't think that an element like:

<count> <'count' characters>

is universal enough to warrant special language features. Since there
are can dozens of different elements, all mixed up, and in sequences
which themselves have a count field. Or count fields could themselves be
variable length.

Here's a challenge for you: a binary file has already been loaded into
memory, and P is a char* pointer, pointing into part of it that has this
stringtable data, very similar to your count/string pairs:

<number of strings> # int32 (assume suitable endian)
<length1> # int32
<string1> # length1 bytes, not 0-terminated
<length2>
<string2>
...
<lengthN>
<stringN>

Now that you variable-element-length arrays, how would you define data
structures, for this, and how would it be initialised from P? Please, no
magic!

Here's a variation; we still want the lengths accessible, but they have
to be determined:

<number of strings>
<string1> # zero-terminated string
<string2>
...
<stringN>

Here's a variation of that first one:

Just before P was this tag:

<tag meaning string table follows>

P points here:
<length1> # int32
<string1> # length1 bytes, not 0-terminated
<length2>
<string2>
...
<0xFFFFFFFF> # int32, means end of string table
<stringN>

Another variation of the first, is where the strings are zero-terminated
(so a length of 10 means 10+1 bytes follow).

Beyond that is gets too complex to have a static data structure, for
example with mixed, variable content.

Chris M. Thomasson

unread,
Jun 14, 2020, 8:53:51 PM6/14/20
to
On 6/12/2020 8:10 PM, rick.c...@gmail.com wrote:
> Chris Thomasson, I wanted to get your input. Maybe there's already
> a syntax to handle these cases in C or C++.
>
> I have a class or struct defined at some point like this:
>
> struct SWhatever
> {
> void* data; // Reference to user-data
> };
>
> In some module of my application, I know that the data member
> will be some other structure and no longer needs to be referenced
> as void*. I can now reference it directly by the type that's used
> in that module.
>
> What syntax could I create to augment that member with later known
> types? I am considering this syntax:
>
> struct SMyWhatever : SWhatever
> {
> augment SList* data; // Changes void* to SList*
> };
[...]

At first glance maybe something like:
________________________
#include <iostream>


struct SWhatever
{
void* data;
};


struct SFoo
{
SFoo(int data_) : data(data_)
{
std::cout << this << "::SFoo::SFoo(" << data << ")\n";
}

~SFoo()
{
std::cout << this << "::SFoo::~SFoo(" << data << ")\n";
}

int data;

void bar()
{
std::cout << this << "::SFoo::bar(" << data << ")\n";
}
};


struct SWhateverShim
{
SWhatever whatever;

SWhateverShim(SWhatever const& whatever_) : whatever(whatever_) {}

SFoo* get() const
{
return static_cast<SFoo*>(whatever.data);
}

SFoo* operator ->() const
{
return get();
}
};


int main()
{
{
SWhatever wever;

wever.data = reinterpret_cast<void*>(new SFoo(123));

SWhateverShim shim(wever);

shim->bar();

delete shim.get();
}

return 0;
}
________________________


Is that helpful at all Rick?

Chris M. Thomasson

unread,
Jun 15, 2020, 2:45:18 AM6/15/20
to
On 6/12/2020 8:10 PM, rick.c...@gmail.com wrote:
> Chris Thomasson, I wanted to get your input. Maybe there's already
> a syntax to handle these cases in C or C++.
>
> I have a class or struct defined at some point like this:
>
> struct SWhatever
> {
> void* data; // Reference to user-data
> };
>
> In some module of my application, I know that the data member
> will be some other structure and no longer needs to be referenced
> as void*. I can now reference it directly by the type that's used
> in that module.
>
> What syntax could I create to augment that member with later known
> types? I am considering this syntax:
[...]

You want syntactic sugar over all of this? For your new language?

Here is something very basic, no sugar:

For some reason you are making me think of pascal strings and variable
length arrays.

_______________________________
#include <iostream>
#include <cstddef>
#include <cstdlib>
#include <cstring>


struct header
{
std::size_t m_size;

char* get_buf()
{
return reinterpret_cast<char*>(this + sizeof(*this));
}
};


header* header_alloc(std::size_t size)
{
header* const h = reinterpret_cast<header*>(std::malloc(sizeof(*h) +
size));

if (h)
{
h->m_size = size;
}

return h;
}


void header_free(header* h)
{
std::free(h);
}


int main()
{
{
header* h = header_alloc(123);

if (h)
{
char* buf1 = h->get_buf();

std::strcpy(buf1, "Hello");

std::cout << "buf1 = " << buf1 << "\n";
std::cout << "h->m_size = " << h->m_size << "\n\n";


char* buf2 = h->get_buf();

std::strcat(buf2, " World");

std::cout << "buf2 = " << buf2 << "\n";
std::cout << "h->m_size = " << h->m_size << "\n\n";

header_free(h);

if ((h = header_alloc(42)))
{
std::strcpy(buf1, "FortyTwo");

std::cout << "buf1 = " << buf1 << "\n";
std::cout << "h->m_size = " << h->m_size << "\n";

header_free(h);
}
}
}

return 0;
}
_______________________________


Help at all?

Chris M. Thomasson

unread,
Jun 15, 2020, 2:50:19 AM6/15/20
to
On 6/14/2020 11:45 PM, Chris M. Thomasson wrote:
> On 6/12/2020 8:10 PM, rick.c...@gmail.com wrote:
>> Chris Thomasson, I wanted to get your input.  Maybe there's already
>> a syntax to handle these cases in C or C++.
[...]
> int main()
> {
>   {
>       header* h = header_alloc(123);
>
>       if (h)
>       {
>         char* buf1 = h->get_buf();
>
>         std::strcpy(buf1, "Hello");
>
>         std::cout << "buf1 = " << buf1 << "\n";
>         std::cout << "h->m_size = " << h->m_size << "\n\n";
>
>
>         char* buf2 = h->get_buf();
>
>         std::strcat(buf2, " World");
>
>         std::cout << "buf2 = " << buf2 << "\n";
>         std::cout << "h->m_size = " << h->m_size << "\n\n";
>
>         header_free(h);
>
>         if ((h = header_alloc(42)))
>         {

/// ARGH! I forgot to put in:

buf1 = h->get_buf();


>           std::strcpy(buf1, "FortyTwo");
>
>           std::cout << "buf1 = " << buf1 << "\n";
>           std::cout << "h->m_size = " << h->m_size << "\n";
>
>           header_free(h);
>         }
>       }
>   }
>
>   return 0;
> }
> _______________________________
>
>
> Help at all?

Sorry for the bug. Self slap here. Can you find any more? ;^)

Correction:

Chris M. Thomasson

unread,
Jun 15, 2020, 3:01:22 AM6/15/20
to
[...]

Should that be:

struct header
{
std::size_t m_size;

char* get_buf()
{
return reinterpret_cast<char*>(this + 1);
}
};

Is that even Kosher with C++ using the this pointer?

rick.c...@gmail.com

unread,
Jun 15, 2020, 11:30:37 AM6/15/20
to
Yes. That was the whole goal of this feature:

// Save constructed packet to disk
FILE* fh = fopen("packet.txt", "wb+");
if (fh)
{
fwrite(data, 1, sizeof(data), fh);
fclose(fh);

// Load it back in
SDay* d = (SDay*)malloc(sizeof(data));
if (d)
{
fh = fopen("packet.txt", "rb+");
if (fh)
{
fread(d, 1, sizeof(data), fh);
fclose(fh);

// Display contents of both, one from memory, one from disk without parsing
SDay* dMem = data;
SDay* dDisk = d;

for (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i, ++dMem, ++dDisk)
{
printf("Memory: %d %04d %s\n", i, dMem->length, dMem->name);
printf("Disk: %d %04d %s\n", i, dDisk->length, dMem->name);
}
}
}
}

The same would work over a network. No pre-processing to access
members. And validation members can be added with magic numbers
to ensure it’s of the correct form, or CRC to ensure nothing was
lost in transmission.

It's a very common need, and this extension would address it.
Will look at this part of your message this evening.

--
Rick C. Hodgin

Bart

unread,
Jun 15, 2020, 4:53:58 PM6/15/20
to
On 15/06/2020 16:30, rick.c...@gmail.com wrote:
> On Sunday, June 14, 2020 at 10:50:54 AM UTC-4, Bart wrote:

>> What it doesn't have is a flat, inline replesentation of the data. But
>> if this is supposed to mirror what is going on in an external file
>> (perhaps via mmap), then I don't think that an element like:
>>
>> <count> <'count' characters>
>>
>> is universal enough to warrant special language features. Since there
>> are can dozens of different elements, all mixed up, and in sequences
>> which themselves have a count field. Or count fields could themselves be
>> variable length.
>
> Yes. That was the whole goal of this feature:
>
> // Save constructed packet to disk
> FILE* fh = fopen("packet.txt", "wb+");
> if (fh)
> {
> fwrite(data, 1, sizeof(data), fh);
> fclose(fh);
>
> // Load it back in
> SDay* d = (SDay*)malloc(sizeof(data));
> if (d)
> {
> fh = fopen("packet.txt", "rb+");
> if (fh)
> {
> fread(d, 1, sizeof(data), fh);

Here, you wouldn't normally know the size of 'data' (assuming this is
one of your new kinds of structs). The size depends on the strings it
contains.

Let me ask: if the block of data you've read constains N pairs of
lengths and strings, once it is read into your SDay structure (which
let's say is defined, conveniently, with N pairs of length and strings
too), how does the program locate the offset of the length of the i'th
length (the offset of the i'th string will be 4 bytes further on)?

(I say offset, but you seem to have dropped the idea of using structs
with multiple strings, for an array of single-string elements, using a
flat representation with variable-length elements.)

What magic is performed to do that? And if there is no magic, you just
have to schlepp along the data just as I showed in my getstrn()
function, that what is the point of creating an extensive language
feature just for that one specific data format, out of dozens of
possible such layouts?

In any case, as I understand C++, you can achieve this anyway in that
language; that is, access the fields as though they were at the same
fixed offsets of a normal struct, and adapt that for a number of
different formats. But even without C++, any ordinary language can
access the same; see my example below.


> fclose(fh);
>
> // Display contents of both, one from memory, one from disk without parsing
> SDay* dMem = data;
> SDay* dDisk = d;
>
> for (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i, ++dMem, ++dDisk)
> {
> printf("Memory: %d %04d %s\n", i, dMem->length, dMem->name);
> printf("Disk: %d %04d %s\n", i, dDisk->length, dMem->name);

Don't forget that strings are supposed to be non-zero-terminated; this
needs more work.

> }
> }
> }
> }

This is another example using the code I posted previously. First, to
create an external file containing the binary data, I used this script:

strings:=("One","Two","Three","Four")

f:=createfile("data")
forall s in strings do
outlong(f,s.len)
print @f,s
od
outlong(f,0xFFFFFFFF)

closefile(f)

This produces this binary file (might wrap)

0000: 03 00 00 00 4f 6e 65 03 00 00 00 54 77 6f 05 00
[....One....Two..]
0010: 00 00 54 68 72 65 65 04 00 00 00 46 6f 75 72 ff
[..Three....Four.]
0020: ff ff ff [...]

Now I can read it with this C code, using the routines I've posted
(tweaked for non-zero-termonated), and a routine 'readfile', not shown:

int main(void) {
char* s;
char* data;
int nstrings, length;

data = readfile("data");

nstrings = countstrings(data);

for (int i=1; i<=nstrings; ++i) {
length = getlength(data,i);
s = getstring(data,i);

printf("%d: %04d \"%.*s\"\n",i,length,length,s);
}
}

It displays:

1: 0003 "One"
2: 0003 "Two"
3: 0005 "Three"
4: 0004 "Four"

Determining the size and/or end of the data is still an issue, something
you've glossed over, but I've had to deal with it because mine is actual
working code, unlike yours. So I used a sentinel still.

rick.c...@gmail.com

unread,
Jun 15, 2020, 6:15:41 PM6/15/20
to
fseek(fh, 0, SEEK_END);
int size = ftell(fh);
fseek(fh, 0, SEEK_SET);

SDay* d = (SDay*)malloc(size);

And if you're receiving data over a network, you know the packet size
by one of a multitude of ways.

> Let me ask: if the block of data you've read constains N pairs of
> lengths and strings, once it is read into your SDay structure (which
> let's say is defined, conveniently, with N pairs of length and strings
> too), how does the program locate the offset of the length of the i'th
> length (the offset of the i'th string will be 4 bytes further on)?

I don't know where the disconnect is, but the purpose of defining this
variable length structure is so that you can pass data of varying
lengths, or no data, as a data object or an array element if in a list,
and process it without having to jump through coding hoops to do so.
The compiler hides all of the access code. You just deal with members
as though they were fixed.

The only requirement is, the lengths defining variable portions have to
be defined in the structure before their variable portion counter-part,
so that the length is a constant.

> (I say offset, but you seem to have dropped the idea of using structs
> with multiple strings, for an array of single-string elements, using a
> flat representation with variable-length elements.)

I used your example back to you. The important part of the struct
definition is the two-element pair:

int length;
char variable_data[0..length];

You can have as many of those as you want in your struct.

> What magic is performed to do that? And if there is no magic, you just
> have to schlepp along the data just as I showed in my getstrn()
> function, that what is the point of creating an extensive language
> feature just for that one specific data format, out of dozens of
> possible such layouts?

Because it is fast. You pass data, and it's already ready to be read.
If I know I'm receiving an email, I can define an SEmail struct, with
all of the variable components it might have, and then access them in
a fixed manner with zero parsing and immediate access to all members.

> In any case, as I understand C++, you can achieve this anyway in that
> language; that is, access the fields as though they were at the same
> fixed offsets of a normal struct, and adapt that for a number of
> different formats. But even without C++, any ordinary language can
> access the same; see my example below.

I know of no way to do that. And especially not with the simple syntax
this extension has.
Okay, code up your example with this form:

struct SAttachment
{
int type;
int length;
char attachment_data[0..length];
};

struct SEmail
{
int length_from;
int length_to;
int length_cc;
int length_bcc;
int length_subject;
int length_header;
int length_body;
int attachmentCount;

char from [0..length_from];
char to [0..length_to];
char cc [0..length_cc];
char bcc [0..length_bcc];
char subject [0..length_subject];
char header [0..length_header];
char body [0..length_body];

// Label is an offset to a location in the structure, but
// one that doesn't consume data space.
label attachments; // Begins a series of SAttachment
// structs of attachmentCount ele-
// ments long.
};

You pass the SEmail struct over the network, or write it to disk and
read it back in later. When you do, everything is already defined.
You reference each member by its name and the compiler injects code
to compute the correct offset for you.

SEmail* e = get_email();
int handle = prepare_email(e->from, e->to, e->cc, e->bcc,
e->subject, e->header, e->body);

SAttachment* a = e->attachments; // No type checking
for (int i = 0; i < e->attachmentCount; ++i)
prepare_attachment(a->type, a->length, a->attachment_data);

That simple bit of source code would allow you to express variable
length data items so beautifully in code, while hiding the variable
access portions of everything.

Yes it's a desirable feature.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 15, 2020, 6:25:37 PM6/15/20
to
On Sunday, June 14, 2020 at 10:50:54 AM UTC-4, Bart wrote:
> Here's a challenge for you: a binary file has already been loaded into
> memory, and P is a char* pointer, pointing into part of it that has this
> stringtable data, very similar to your count/string pairs:
>
> <number of strings> # int32 (assume suitable endian)
> <length1> # int32
> <string1> # length1 bytes, not 0-terminated
> <length2>
> <string2>
> ...
> <lengthN>
> <stringN>
>
> Now that you variable-element-length arrays, how would you define data
> structures, for this, and how would it be initialised from P? Please, no
> magic!

The purpose of this new feature is that you define the data type at
the generation side, and at the consumption side, which is on the
other side of some kind of data interchange, be it over a network,
be it saved to a disk file and later loaded for batch processing,
be it for inter-process communication within a single system, or
whatever.

The same SWhatever struct is defined to create it. The same SWhatever
struct is defined to read it.

The purpose is data interchange between a source and a destination.

I've had the consideration about how to address your need above.
You essentially have two pieces of incoming data. The first is
the count (number of strings). The second is a list of the type
of struct I'm creating:

struct SString
{
int32 length;
char string[0..length];
};

You would set the SString* variable to where length1 starts, and
then simply iterate:

int count = *(int32*)P;
SString* s = (SString*)((char*)P + sizeof(int32));

for (int i = 0; i < count; ++i, ++s)
{
// s->string is available here
}

> Here's a variation; we still want the lengths accessible, but they have
> to be determined:
>
> <number of strings>
> <string1> # zero-terminated string
> <string2>
> ...
> <stringN>

This requires parsing because it's zero-terminated.

> Here's a variation of that first one:
>
> Just before P was this tag:
>
> <tag meaning string table follows>
>
> P points here:
> <length1> # int32
> <string1> # length1 bytes, not 0-terminated
> <length2>
> <string2>
> ...
> <0xFFFFFFFF> # int32, means end of string table
> <stringN>

for (SString* s = (SString*)P; s->length != -1; ++s)
{
// s->string is available here
}


> Another variation of the first, is where the strings are zero-terminated
> (so a length of 10 means 10+1 bytes follow).
>
> Beyond that is gets too complex to have a static data structure, for
> example with mixed, variable content.

Anything with a NULL-termination that marks the end of the string,
like a typical C string, requires parsing.

That's what this variation is seeking to avoid. It requires zero pre-
parsing before use, at the expense of storing the string lengths, and
the modifications to the C/C++ compiler.

--
Rick C. Hodgin

Chris M. Thomasson

unread,
Jun 15, 2020, 6:27:32 PM6/15/20
to
On 6/15/2020 3:25 PM, rick.c...@gmail.com wrote:
> On Sunday, June 14, 2020 at 10:50:54 AM UTC-4, Bart wrote:
>> Here's a challenge for you: a binary file has already been loaded into
>> memory, and P is a char* pointer, pointing into part of it that has this
>> stringtable data, very similar to your count/string pairs:
[...]
>

As a starter, take a look at DCOM:

https://en.wikipedia.org/wiki/Distributed_Component_Object_Model

Or Corba.

Bart

unread,
Jun 15, 2020, 8:00:35 PM6/15/20
to
According to your initial posts, your binary data looks like this:

3 0 0 0 O n e 3 0 0 0 T w o 5 0 0 0 T h r e e 4 0 0 0 F o u r

Which ever way you do it, getting the length of the 4th string and the
start of the fourth string, involves reading the 1st length "3", using
that to calculate the offset of the 2nd length, reading that, using it
to calculate the offset of the 3rd length, and using that to get the
offset of the fourth length.

It's this business which you haven't gone into any detail over, and
hidden behind compiler magic.

You say this is fast; not if you /always/ have to this calculation to
randomly access the i'th string in the struct.

You then switched to arrays of a struct containing only one
length/string, but this is exactly the same; here ' marks the divisions
between elements:

3 0 0 0 O n e ' 3 0 0 0 T w o ' 5 0 0 0 T h r e e ' 4 0 0 0 F o u r

You now have an array of structs, with sizes of 7, 7, 9 and 8 bytes. The
problem is the same, but accessing by index instead of by name.

>
> The only requirement is, the lengths defining variable portions have to
> be defined in the structure before their variable portion counter-part,
> so that the length is a constant.
>
>> (I say offset, but you seem to have dropped the idea of using structs
>> with multiple strings, for an array of single-string elements, using a
>> flat representation with variable-length elements.)
>
> I used your example back to you. The important part of the struct
> definition is the two-element pair:
>
> int length;
> char variable_data[0..length];
>
> You can have as many of those as you want in your struct.

With the complications of getting the offsets of all those other strings.


>> What magic is performed to do that? And if there is no magic, you just
>> have to schlepp along the data just as I showed in my getstrn()
>> function, that what is the point of creating an extensive language
>> feature just for that one specific data format, out of dozens of
>> possible such layouts?
>
> Because it is fast. You pass data, and it's already ready to be read.
> If I know I'm receiving an email, I can define an SEmail struct, with
> all of the variable components it might have, and then access them in
> a fixed manner with zero parsing and immediate access to all members.
>
>> In any case, as I understand C++, you can achieve this anyway in that
>> language; that is, access the fields as though they were at the same
>> fixed offsets of a normal struct, and adapt that for a number of
>> different formats. But even without C++, any ordinary language can
>> access the same; see my example below.
>
> I know of no way to do that. And especially not with the simple syntax
> this extension has.

Syntax is easy to think up. But it has to make sense and it has to be
implementable. And worthwhile.
You've lost me. You've now changed from length/string/length/string, to
length/length/string/string. I guess further magic means the language
can figure out the format by itself and match each int to each string
(and I further guess that you can't have any other fields in there to
mess things up).

Remember the compiler sees only a series of:

T x;
U y;
V y;
....

And somehow, it has to know that some of those are counts, and are
associated with another member later on. Which is not necessarily an
array, according to your example.

I reckon what you want here is an embedded language to define binary
file layouts. That's fine, but keep it out of the way of the main
language. It is unnecessary to allow access via normal member/index
operations, but as I said, C++ can do that if you want (you may have to
write A.B() instead of A.B).

(BTW is that really an email header? I thought it was 100% text with
nothing as crude as binary string lengths.)

> When you do, everything is already defined.
> You reference each member by its name and the compiler injects code
> to compute the correct offset for you.
>
> SEmail* e = get_email();
> int handle = prepare_email(e->from, e->to, e->cc, e->bcc,
> e->subject, e->header, e->body);
>
> SAttachment* a = e->attachments; // No type checking
> for (int i = 0; i < e->attachmentCount; ++i)
> prepare_attachment(a->type, a->length, a->attachment_data);


> That simple bit of source code would allow you to express variable
> length data items so beautifully in code, while hiding the variable
> access portions of everything.
>
> Yes it's a desirable feature.

How's how I might set that up in script:

email := ["From":"A", "To":B, "CC":"C", "BCC":"D",
"Subject":"E", "Header":"F", "Body":"G"]


I don't believe that email uses rigid binary formats, but even if it
did, that is an external format; you don't use such formats in program
data. You use whatever is simplest to do. This here is variable length
data. The elements can also be specified in any order.

If you don't have such a feature, then add that first. If you do it
properly, you can superimpose an auxiliary data structure on top of
flat, packed binary data.


rick.c...@gmail.com

unread,
Jun 15, 2020, 8:37:17 PM6/15/20
to
You're not getting it, Bart.

Don't worry about it.

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 16, 2020, 7:45:51 AM6/16/20
to
On 16/06/2020 01:37, rick.c...@gmail.com wrote:
> You're not getting it, Bart.
>
> Don't worry about it.

Oh Bart gets it alright: what you are proposing, as usual, is total nonsense.

rick.c...@gmail.com

unread,
Jun 16, 2020, 8:24:01 AM6/16/20
to
Bart, consider this portion:

On Monday, June 15, 2020 at 6:15:41 PM UTC-4, rick....@gmail.com wrote:
> The only requirement is, the lengths defining variable portions have
> to be defined in the structure BEFORE their variable portion counter-
> part, so that the length is a constant [from that variable portion's
> point of view].
>
> The important part of the struct definition is the two-element pair:
>
> int length;
> char variable_data[0..length];
>
> You can have as many of those as you want in your struct.

You said I changed from length/string length/string to length/length
string/string. I didn't change. It was a different layout of the
same type of example.

The point is: you have a variable length variable defined SOMEWHERE
in the struct BEFORE the variable portion, but it doesn't matter where
it's defined.

Once you have the length defined at some point, the variable-length
portion is fully accessible because the length provides access to it.
I made the email struct with the lengths up top so it's clearer visu-
ally.

The email example could've been written this way:

struct SEmail
{
int length_from;
char from [0..length_from];

int length_to;
char to [0..length_to];

int length_cc;
char cc [0..length_cc];

int length_bcc;
char bcc [0..length_bcc];

int length_subject;
char subject [0..length_subject];

int length_header;
char header [0..length_header];

int length_body;
char body [0..length_body];

// Label is an offset to a location in the structure, but
// one that doesn't consume data space.
int attachmentCount;
label attachments; // Begins a series of SAttachment
// structs of attachmentCount ele-
// ments long.
};

In each case, the "len" variable portion referenced inside the
[0..len] syntax simply has to be a named member defined up higher
in the struct.

Do you understand?

Access to each variable would be given by a calculation, assume
sizeof(int) = 4:

from = sizeof(length_from)
to = from + length_from + sizeof(length_to)
cc = to + length_to + sizeof(length_cc)
bcc = cc + length_cc + sizeof(length_bcc)
subject = bcc + length_bcc + sizeof(length_subject)
header = subject + length_subject + sizeof(length_header)
body = header + length_header + sizeof(length_body)
attachments = body + length_body + sizeof(attachmentCount)

The compiler injects functions or inline code to compute the off-
sets so you navigate each structure member as requested.

In this example, ++ would not work properly because it has an
extra variable portion not defined in the structure, but rather
defined behind program logic to access the attachments label
and process the content internally. Moving past that portion
would require determining the size the attachments and either
storing it on the original structure as an extra value that is
not computed, but can be referenced and used in pointer math,
or to traverse the SAttachment members and compute the value at
runtime and use that value.

If attachmentCount is 0, then ++ would work because the pointer
math would be correct in the absence of the "hidden" attachments
size.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 16, 2020, 8:56:42 AM6/16/20
to
On Tuesday, June 16, 2020 at 7:45:51 AM UTC-4, Mr Flibble wrote:
> "Snakes didn't evolve, instead talking snakes with legs changed
> into snakes." - Rick C. Hodgin


The correct statement would be

> “You won’t burn in hell. But be nice anyway.” – Ricky Gervais

Satan teaches that we'll be fine by doing positive things, that our
good will outweigh our bad, and that's good enough. That is a lie.
All of us carry sin, and that sin is like a charge on a rap sheet.
In God's court, that charge will be read aloud and the sentence
will be meted without mercy for all who are guilty. God has warned
us of this in advance, and given us the way out. Each person will,
therefore, send themselves to Hell by their personal rejection of
God.

> “I see Atheists are fighting and killing each other again, over
> who doesn’t believe in any God the most. Oh, no..wait.. that
> never happens.” – Ricky Gervais

All of the war, all of the disease, all of the death, all of the
pain, all of the harmful weather/elements, every poisonous thing,
every thorny thing, all of it comes from one original sin by Adam.

The world Jesus will restore is a return to an Eden-like existence,
where all animals will be at peace, where babies can lay down in
nests of snakes and not have any fear of being bitten.

The Bible promises a future of love and peace, and there will be
a 1,000 year reign of that peace here on Earth, after which Satan,
who was bound up for that 1,000 years unable to influence anybody,
will be loosed at the very end for a short time. And in that very
short time (likely weeks or months (much less than a year) at most),
a large percentage of mankind who has lived during the Millennium
with Jesus, in love and peace, will follow after Satan because of
his silvery tongue and appealing ways. And everyone who does will
be destroyed by fire from God from Heaven.

People do not want God. They invent every possible excuse to have
their own way, to do their own things. They hide behind national
pride, behind a constructed moral charter, behind anything that can
give them a rallying cry. But when they build up on something other
than Jesus Christ and His teachings, they are in rebellion against
God, no matter how "noble" their goals might seem.

Jesus provides us a framework for life and living which is expansive
and comprehensive. The only frames that are in place are to keep us
from going astray and becoming part of a force which would serve to
destroy His creation. He governs His creation with an iron rod, and
does not tolerate that which rises up against it.

Consider all of the wars, all of the death, all the disease, all the
pain, stemmed from ONE SIN by Adam. Sin is like cancer. Once it
shows up, it spreads. It destroys good tissue and replaces it with
cancerous tissue. Once sin shows up it destroys good society, and
replaces it with destructive society. It's evident everywhere.

God will not tolerate sin. Either we will pay the price for our sin,
or Jesus will. All who put their faith and trust in Jesus will never
see death, will never be ashamed, will never be cast down for their
sin, but have passed (past tense) from death to life and will enter
in to eternity alive.

It's the greatest gift imaginable. Despite our guilt, despite our on-
going rebellion against God in all our various ways, yet is He patient
and desirous of us. He goes out of His way to send message after mes-
sage and messenger after messenger to reach every last person.

> "Suppose it's all true, and you walk up to the pearly gates, and
> are confronted by God," Byrne asked on his show The Meaning of
> Life. "What will Stephen Fry say to him, her, or it?"
> "I'd say, bone cancer in children? What's that about?" Fry replied.
> "How dare you? How dare you create a world to which there is such
> misery that is not our fault."

Here is where Fry errs. It is our fault. God created the perfect
paradise and created a special garden called Eden and put man in it.
There the Bible records "the cool of the day." Everything was pro-
vided for man. All Adam and Eve had to do was keep it, which I would
argue at that point would be via something we would call supernatural,
kind of how Jesus was able to perform miracles when He walked the
Earth. Adam and Eve could summon abilities we would consider magic.
Move things with their thoughts. Instantiate instances of things
here on the Earth likewise. It would be like looking in your back
yard and thinking to yourself, "I wish I had a rose garden there,"
and Adam and Eve could have that thought and then think, "Behold, a
rose garden," and it spontaneously appeared there based on the very
template of their thoughts.

That ability was lost because of sin. Everything God created for us
was lost because of sin, all except our physical life here in the
flesh. Our eternal nature, our spirit, the unity of our soul + body
+ spirit were all lost. We now stand in defeated isolation with ac-
cess to our physical body.

The enemy anti-Christ spirit is able to exert spiritual forces by
their will which manipulate our flesh. They can inject thoughts and
feelings and emotions into our physical reality. These things we
think we feel, including homosexuality, addiction, lusts, passions,
thoughts like those of severe criminals who say, "The voice told me
to kill that person," actually stem from a real source, which is
that of those evil spirits at work against all of us continually.

The Bible teaches us the nature of this attack, and how to overcome
it. The ability to overcome stems completely and totally from Jesus
Christ alone, because ONLY JESUS can take away our sin. When our
sin is taken away, those things we lost when our sin was taken away
are restored, and we begin the journey of learning how to be proper
people in this world, guided by God's Holy Spirit, guided by our
inner drive to seek and pursue the truth and learn of the truth God
teaches us, to un-learn the things of this world the enemy has
taught.

Leigh, you spin and toil in the world of physicality. And while
none of us can break the chains of our ties to this flesh, what
Jesus teaches us is that we don't have to be beholden to it. That
our spirit nature, which He gives us when He takes our sin away,
can overcome our flesh, that we can pursue the spirit rather than
the flesh and no longer be a slave to the flesh.

You reject that teaching because of the influences of the many evil
spirits you've let into your life by your choices over the years.
They give you thoughts, feelings, ideas, emotions, that rail against
all things related to Jesus Christ, so that you are a slave to your
flesh, which makes you a slave to them, which keeps you on the path
to destruction.

If you want to break free, you have to begin with an attitude of the
heart toward seeking the truth, of seriously wanting to know if
these things I teach, that the Bible teach, are really real or not.
When you come to that place of honestly seeking the truth of things
for knowledge' sake, God knows you are doing this and He comes to you
with truth ... because He is truth, and when you seek truth He sees
you seeking Him.

There's so much more to this world and eternity than your world-view
provides in your understanding. God has prepared the most amazing
things for us, His greatest creation, made in His own image and like-
ness. And it is that existence the enemies of God (evil spirits)
have lost, and it is the ability to be restored to that existence
that those same enemies try to prevent all of us from coming to the
knowledge of, so that we remain where we are, lost in sin.

You have the ability to be restored to eternity, Leigh. You can have
that amazing future God intended for each of us before sin entered in
and destroyed everything. Yet even in our sin, God has made the way
back for free.

You owe it to yourself to seek this out. Everybody owes it to them-
selves to seek this out. It's not a lie, and you'll find the extent
to which Jesus is truly and absolutely and totally and completely
amazing beyond words in that He still cares about us even in our
guilt and shame from sin.

> It's not right, it's utterly, utterly evil."

Satan twists things in people's thinking so that those things which
are of God are evil, and those things which are of Satan's own influ-
ence are pushed onto God as though He's the cause of the negative
things, when it is that very enemy of God who was the source of it
all.

Satan will soon be cast into the eternal lake of fire for what he
has done. The power and authority here in this world he affords
those who follow after him is temporal, fleeting, and has no real
foundation or stability and will not endure. People pursue after
it because it's tempting to the flesh. But if you press in and seek
the truth and come to Jesus and are forgiven of sin and your spirit
comes alive, you begin to receive true and proper input from God,
which re-focuses your attention on the important things to God,
which fills you with inner joy, peace, love, and overflowing to such
an extent that you reach out with both arms, proclaiming with your
mouth as you go, those things that are possible in Jesus Christ.

> "Why should I respect a capricious, mean-minded, stupid God who
> creates a world that is so full of injustice and pain. That's
> what I would say."

God created a world that was perfect. Sin has introduced all of
those things Fry's railing against. What Fry hates is Satan and
the evil he brought. Fry's attributing the evil to God because
he is ignorant of the truth. It's how all people will wind up in
Hell. They ignore the offering of Jesus because they rely on
their flesh for understanding, and that enemy of God feeds their
flesh with a multitude of lies which are purported and held up by
a vast avenue of aligned resources to seem as though it's true.

But when one takes the time to investigate the alleged "facts" of
each of those lies, they crumble under scrutiny, because God is
still in control, His power is still absolute, and He doles out
victory after victory after victory in truth, and all of it is
there waiting for us to seek.

Were Fry to investigate his claims, he would realize that the very
thing he's railing against is sin and sin's effect on this world.
He would seek the world God created, and will restore, where there
is no cancer in babies, where there is no pain or death or hunger
or thirst as we know it.

The enemy is a liar and the father of lies. If you want to be set
free from the lies, seek the truth. Jesus is truth. Learn of Him
and He will set you free, and restore you to His eternal Kingdom of
power and love and peace and joy and beauty and honor.

--
Rick C. Hodgin

rick.c...@gmail.com

unread,
Jun 16, 2020, 9:16:17 AM6/16/20
to
On Tuesday, June 16, 2020 at 8:56:42 AM UTC-4, rick....@gmail.com wrote:
> On Tuesday, June 16, 2020 at 7:45:51 AM UTC-4, Mr Flibble wrote:
> > "Snakes didn't evolve, instead talking snakes with legs changed
> > into snakes." - Rick C. Hodgin
>
> The correct statement would be

The correct statement would be:

The world God created in the beginning was markedly different
than the world we live in now. We live in the world of sin's
creation, which is a diminished world compared to that we had
in the Garden of Eden.

Lifespans are shorter. People changed after sin. The inner
character of their nature, the donning of reality has become
limited to flesh-focused things. We are lesser now that we
have lost our relationship with God, and His mighty hand of
direct daily intervention and protection as was in effect in
the garden.

How did this happen? The serpent introduced an alternative
idea, proposed something other than that which God had pre-
viously guided Adam and Eve toward. He introduced a lie, and
purported it as though it were truth. Adam and Eve believed
the lie and followed after the guidance of the serpent, which
then immediately introduced sin. The Bible records "their
eyes were opened" and they knew that they were naked, for ex-
ample.

God came to Adam and Eve after this and inquired as to why
they had hid themselves. When God discovered they had fol-
lowed after the guidance of the serpent, God's anger moved
toward the serpent and in that instant God changed the form-
erly beautiful creature into that which we would call a snake
today. No longer does it have legs and a form to move about,
but its spine was extended, its insides were altered, its
whole demeanor and type of existence was changed, so that now
the creature serves as the embodiment of how Satan moves.

Snakes lie in wait. They attack from hidden places. Many
have venom that can kill once it gets on the inside of your
flesh. They can unhinge their jaw and consume things that
are bigger than they are.

God has given us all of this knowledge about the serpent in the garden,
and the snakes we have today, to teach us some things about the nature
of what we all face.

You put a tag onto all of your messages where you mock me by putting a
quote I never originated, twisting it into something mocking because
you believe that you are being commensurately insulting back to me for
the "infliction" I subject this group to.

What you don't realize is that the things I post with regards to Christ
are the very things we need to have eternal life, to be restored, to
seek the truth, to know real love, real peace, real joy. And that, be-
cause of sin, you are listening to voices intent on keeping you pinned
up in your sin, condemned in eternity, so that you are not set free as
Jesus would allow you be, and has provided for you to be.

You take hold of the enemy's guidance within your flesh because the
flesh is all you know, and you're following it so intently. You are
not willing to step out into the area of questioning something that
your flesh peddles to you. You are not willing to ask yourself if
the behavior you're engaging in (constant profanity, always being in-
sulting and rude to people, mocking me, all of which are signals to
the general pattern you would have toward everyone in your daily
life) is actually beneficial, proper, desirable, fruitful, product-
ive, or other such things.

You continue on like a brute beast following only its flesh-focused
baser feelings and emotions, never using the ample mind of full-on
contemplation God gave you to consider something more.

You don't know the beauty you possess, Leigh. You don't know the
hand-crafted form you be restored to by God's creation. You don't
know the future of beauty and glory and honor and truth and power
and love you can be a part of. The enemy has deceived you into be-
lieving that this flesh-focused nature is where it's at, and you
have to get ahead by using your assets and pushing other people
down rather than lifting them up and being part of their lives in
some positive way.

"Talking snakes with legs didn't turn into snakes," as you put it.
The serpent deceived Adam and Eve, and as a result of that deception,
was forever altered in a way recorded for us to now use our minds and
examine so that we can see the significance God places on sin, and to
also see the incredible love given to us (man) because despite our
full-on guilt in sin, yet is He not only willing to forgive us, but
is exceedingly patient with us, effectively rescuing even the very
souls holding the hammer and nails to put Him on that cross from
their own folly:

http://mrmom.amaonline.com/forgiven.htm

You diminish everything around you, Leigh, when you do not pursue
the truth. When you ride high upon some lie. It's not part of any
aspect of our existence God calls us to. And that reality is self-
evident even to someone who does not believe in God, because it is
also true of simple life and living (falseness and lies never bring
about rightness, they always only bring about destruction and death).

--
Rick C. Hodgin

Bart

unread,
Jun 16, 2020, 12:35:04 PM6/16/20
to
On 16/06/2020 13:23, rick.c...@gmail.com wrote:
> Bart, consider this portion:
>
> On Monday, June 15, 2020 at 6:15:41 PM UTC-4, rick....@gmail.com wrote:
>> The only requirement is, the lengths defining variable portions have
>> to be defined in the structure BEFORE their variable portion counter-
>> part, so that the length is a constant [from that variable portion's
>> point of view].
>>
>> The important part of the struct definition is the two-element pair:
>>
>> int length;
>> char variable_data[0..length];
>>
>> You can have as many of those as you want in your struct.
>
> You said I changed from length/string length/string to length/length
> string/string. I didn't change. It was a different layout of the
> same type of example.
>
> The point is: you have a variable length variable defined SOMEWHERE
> in the struct BEFORE the variable portion, but it doesn't matter where
> it's defined.
>
> Once you have the length defined at some point, the variable-length
> portion is fully accessible because the length provides access to it.
> I made the email struct with the lengths up top so it's clearer visu-
> ally.

But is your new feature supposed to disentangle all that, or must the
fields be in a certain layout?

Your original example used several variable lengths strings in a struct,
different from C's variable struct which only has such an array at the
end, and its size is not automatically linked to an earlier field.

You then moved on to arrays with variable-length structs as in-line
elements, although the struct in your example had only one string. It
still made the array elements different sizes.

Then, you again had a multiple strings in the struct, but this time in
an apparently random order! Or are the lengths supposed to come before
the strings? Is the Nth length supposed to correspond to the Nth
char-array? Is the correspondence achieved by checking whether a simple
bound of the char-array corresponds to the name of an integer field?
(However, if the length comes after the char-array, that cannot work.)

Further, you then introduced a non-char-array element called a 'label'.

It does look exactly as though you are just making it up as you go along.

How about creating mock-ups of how these structures are supposed to
work, using existing language features, and trying them out on real data
using real programs? (A bit like how I tried to do, using explicit
functions.)

Then, you will see how well they function, what code is involved, and
how those handlers you built by hand can be automated by a compiler. I
see that as a necessary step.

> In each case, the "len" variable portion referenced inside the
> [0..len] syntax simply has to be a named member defined up higher
> in the struct.
>
> Do you understand?
>
> Access to each variable would be given by a calculation, assume
> sizeof(int) = 4:
>
> from = sizeof(length_from)
> to = from + length_from + sizeof(length_to)
> cc = to + length_to + sizeof(length_cc)
> bcc = cc + length_cc + sizeof(length_bcc)
> subject = bcc + length_bcc + sizeof(length_subject)
> header = subject + length_subject + sizeof(length_header)
> body = header + length_header + sizeof(length_body)
> attachments = body + length_body + sizeof(attachmentCount)

So, quite a sizable amount of code, probably too much to be done inline,
for each access. A chain of calculations as I suggested.

The chain will be fixed for a struct member with named access, but for
an array of variable structs with an index like 'i', will involve a loop.

As for efficiency, imagine a sequence of 10,000 packed strings, assuming
a format that exactly matches your int32-plus-non-terminated-string.

> The compiler injects functions or inline code to compute the off-
> sets so you navigate each structure member as requested.


You can use this if you want, but most would see this as too low-level
(eg. a string with a separate length, one that you can override so
making it incorrect, yet the string isn't even zero-terminated making
most operations awkward), compared with more modern string objects.

If you want to keep packed binary data in memory, then better to
traverse it once to build auxiliary data, eg. an array of pointers into
the strings, or better, a set of counted-string 'views'into the data.

rick.c...@gmail.com

unread,
Jun 16, 2020, 12:43:41 PM6/16/20
to
On Tuesday, June 16, 2020 at 12:35:04 PM UTC-4, Bart wrote:
> On 16/06/2020 13:23, rick.c...@gmail.com wrote:
> > Once you have the length defined at some point, the variable-length
> > portion is fully accessible because the length provides access to it.
> > I made the email struct with the lengths up top so it's clearer visu-
> > ally.
>
> But is your new feature supposed to disentangle all that, or must the
> fields be in a certain layout?

The only requirement is that the variable portion have a named
member up higher in the struct. It allows the member to have
a presence or not in the struct, and to be from 0..length bytes
long.

> Further, you then introduced a non-char-array element called a 'label'.

That's a feature of CAlive which allows you to access an offset
outside of referencing a typed member name. It allows you to do
math on the internals.

> It does look exactly as though you are just making it up as you go along.

You've misunderstood from the beginning. You've had a thought in
your mind about what it was, and have since run with it. If you
go back and read what I posted you'll see consistency all the way
through.

> How about creating mock-ups of how these structures are supposed to
> work, using existing language features, and trying them out on real data
> using real programs? (A bit like how I tried to do, using explicit
> functions.)
>
> Then, you will see how well they function, what code is involved, and
> how those handlers you built by hand can be automated by a compiler. I
> see that as a necessary step.

If you understand in concept, you'll see how it works. It's very
straight-forward.

> > In each case, the "len" variable portion referenced inside the
> > [0..len] syntax simply has to be a named member defined up higher
> > in the struct.
> >
> > Do you understand?
> >
> > Access to each variable would be given by a calculation, assume
> > sizeof(int) = 4:
> >
> > from = sizeof(length_from)
> > to = from + length_from + sizeof(length_to)
> > cc = to + length_to + sizeof(length_cc)
> > bcc = cc + length_cc + sizeof(length_bcc)
> > subject = bcc + length_bcc + sizeof(length_subject)
> > header = subject + length_subject + sizeof(length_header)
> > body = header + length_header + sizeof(length_body)
> > attachments = body + length_body + sizeof(attachmentCount)
>
> So, quite a sizable amount of code, probably too much to be done inline,
> for each access. A chain of calculations as I suggested.

Yes, all hidden from the developer, allowing the developer to use
the feature without worrying about the mechanics.

> As for efficiency, imagine a sequence of 10,000 packed strings, assuming
> a format that exactly matches your int32-plus-non-terminated-string.

If you have a need for 10,000 things use something else. This is
for the purposes I've outlined. You prepare a message at some
source, transmit to another, and then immediately process it rather
than having to parse it out.

> > The compiler injects functions or inline code to compute the off-
> > sets so you navigate each structure member as requested.
>
> You can use this if you want, but most would see this as too low-level
> (eg. a string with a separate length, one that you can override so
> making it incorrect, yet the string isn't even zero-terminated making
> most operations awkward), compared with more modern string objects.
>
> If you want to keep packed binary data in memory, then better to
> traverse it once to build auxiliary data, eg. an array of pointers into
> the strings, or better, a set of counted-string 'views'into the data.

You are completely missing the point. I wonder sometimes if you
read what I write.

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 16, 2020, 1:15:28 PM6/16/20
to
tl;dr.

/Flibble

--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin

“You won’t burn in hell. But be nice anyway.” – Ricky Gervais

“I see Atheists are fighting and killing each other again, over who doesn’t believe in any God the most. Oh, no..wait.. that never happens.” – Ricky Gervais

"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."

Mr Flibble

unread,
Jun 16, 2020, 1:15:39 PM6/16/20
to
tl;dr.

/Flibble

--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin

“You won’t burn in hell. But be nice anyway.” – Ricky Gervais

“I see Atheists are fighting and killing each other again, over who doesn’t believe in any God the most. Oh, no..wait.. that never happens.” – Ricky Gervais

"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."

rick.c...@gmail.com

unread,
Jun 16, 2020, 2:54:19 PM6/16/20
to
On Tuesday, June 16, 2020 at 1:15:39 PM UTC-4, Mr Flibble wrote:
> tl;dr.

Ironic.

The short version of what I wrote is this:

Satan deceives people into not looking into the details. He
does this so he can keep the false image he's assembled into
their thinking in tact knowing that a real examination of the
facts and data would undo that stranglehold and set the person
free from his lies, allowing that person to know the truth.

You remain deceived by Satan, Leigh, because you are willfully
ignorant. You make the conscious choice not to know.

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 16, 2020, 3:16:14 PM6/16/20
to
And Satan invented fossils, yes?

rick.c...@gmail.com

unread,
Jun 16, 2020, 3:36:38 PM6/16/20
to
On Tuesday, June 16, 2020 at 3:16:14 PM UTC-4, Mr Flibble wrote:
> And Satan invented fossils, yes?

No, but he did invent the lie you use today, again in ignorance.

You're holding on to lies, Leigh. They keep you bound, and will cont-
inue to do so until you begin to seek the truth.

--
Rick C. Hodgin

Mr Flibble

unread,
Jun 16, 2020, 3:47:28 PM6/16/20
to
0 new messages