Saturday, June 13, 2020

Digest for comp.lang.c++@googlegroups.com - 25 updates in 3 topics

rick.c.hodgin@gmail.com: Jun 12 08:10PM -0700

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 <flibbleREMOVETHISBIT@i42.co.uk>: Jun 13 09:58AM +0100

> would work for struct or class, but is more easily visualized in
> example using the struct form above.
 
> What do you think?
 
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 <ben.usenet@bsb.me.uk>: Jun 13 11:11AM +0100


> Chris Thomasson, I wanted to get your input.
 
You should consider using email. This is a group.
 
--
Ben.
Bart <bc@freeuk.com>: Jun 13 12:01PM +0100

> 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.hodgin@gmail.com: Jun 13 04:27AM -0700

On Saturday, June 13, 2020 at 6:11:17 AM UTC-4, Ben Bacarisse wrote:
> rick.c.hodgin@gmail.com writes:
> > Chris Thomasson, I wanted to get your input.
> You should consider using email. This is a group.
 
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.hodgin@gmail.com: Jun 13 06:57AM -0700

On Saturday, June 13, 2020 at 7:02:02 AM UTC-4, Bart wrote:
> > 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.hodgin@gmail.com: Jun 13 07:52AM -0700

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.hodgin@gmail.com: Jun 13 07:56AM -0700


> 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 <flibbleREMOVETHISBIT@i42.co.uk>: Jun 13 03:57PM +0100


> 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.
 
LOL. So 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."
rick.c.hodgin@gmail.com: Jun 13 08:03AM -0700

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 <flibbleREMOVETHISBIT@i42.co.uk>: Jun 13 04:16PM +0100

> 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.
 
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."
Bart <bc@freeuk.com>: Jun 13 04:48PM +0100


> 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.
 
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 <scott69@gmail.com>: Jun 13 06:32PM +0200

> int length;
> var_char data[0..length];
> };
 
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;

No comments: