Template technicality - What does the standard say?

I

Ian Collins

Stephen said:
I'm sorry, but it's basic textbook. The compiler determines what is
inherited and places each inherited class at a particualar offset
within the derived class, as if it were member data (which it is).
This isn't true. See 9.2.12 and 10.0.5.
 
I

Ian Collins

Stephen said:
In my current circumstances, paying for the standard would mean not
eating for a week,

You can live off $18 a week, I'm impressed.
A constraint that means C data structure code cannot be adapted and
wrapped in a C++ template? IIRC, one of the basic design principles of
C++ is that people should be able to adapt their C libraries without a
complete rewrite.
By definition, a C data structure is a POD struct, so you can use offsetof.
Trying to bully people into using member-pointers won't fix the flaws.
offsetof is needed, like it or not. Without it, there is simply *NO*
sane way for library developers to develop production quality
containers.

It's never stopped me, or all the other C++ library writers out there.
 
S

Stephen Horne

You can live off $18 a week, I'm impressed.

Not quite *that* tight, but 'live' is questionable anyway. That's not
the price I saw for the standard (or the one James quoted).

If that price is available, next problem is no credit card. I refuse
to get one so long as I'm on benefits for obvious reasons.
By definition, a C data structure is a POD struct, so you can use offsetof.

template<typename T>
struct This_May_Not_Be_POD
{
T Because_This_May_Not_Be_POD;
};

That's the whole point.
 
S

Stephen Horne

This isn't true. See 9.2.12 and 10.0.5.

The standard has already been quoted at me, but read James' point that
I was replying too - this isn't about the standard, it's about all the
compilers he knows and what he thinks is possible.

I challenge you. First, define a class using *ANY* standard C++
features you please - multiple inheritance and virtual inheritance
included. Lets call this class TEST.

Now, create two instances of TEST. Don't care where you instantiate so
long as you aren't using any further inheritance - global, local,
normal member, static member, anything. Placement new it if you think
that'll make a difference. Just make sure you don't instance any
derived classes - both must be instances of the exact same class, ie
TEST.

Now, show me a compiler - *ANY* compiler - that uses different memory
layouts for those two instances.

Basic science. The easiest way to prove that instances of a single
class can be arranged differently in different cases is to provide an
example, and I'm only asking for one.

You won't find one. The layout of the class isn't dynamic. It may not
be the same as the layout of any classes that inherit from it, but
that's beside the point. Even multiple inheritance would break offsets
if you're looking at derived classes.

Can you imagine what it would be like if one instance of a class was
arranged differently to another instance of that exact same class? Can
you imagine any vaguely coherent reason why a compiler-writer would
choose to introduce pointless nondeterminism like this?

No - of course not.
 
J

James Kanze

I'm sorry, but it's basic textbook. The compiler determines
what is inherited and places each inherited class at a
particualar offset within the derived class, as if it were
member data (which it is).

You must be reading the wrong textbooks (or you don't understand
virtual inheritance), since it's provably impossible to do so.
And it's simple to try:

#include <iostream>

struct VB
{
virtual ~VB() {} ;
int vb ;
} ;

struct M : virtual VB
{
int m ;
void f( std::eek:stream& s )
{
// Equivalent of offsetof, but legal everywhere,
// since we have an actual object...
s << ((char*)&vb - (char*)this) << std::endl ;
}
} ;

struct D : M
{
int d ;
} ;

int
main()
{
M v1 ;
v1.f( std::cout ) ;
D v2 ;
v2.f( std::cout ) ;
return 0 ;
}

I get different values for the two variables with every compiler
I try.
Every inherited class gets a fixed offset,

Impossible when virtual inheritance is involved.
thus every inherited member gets a fixed offset (ignoring
statics etc). Those offsets may not apply for classes that
inherit this derived class, due to the sharing aspect for
virtual inheritance, but that's besides the point - right at
the start I said it was necessary to name the right
struct/class.
We are dealing with a class/struct and a member. No dynamic
issues as there is no dynamic object in the first place.

See the above. Your statements and actual tests don't match.
Yes you can, as mentioned above. The problem is that you're
imagining casting-through-the-class-hierarchy issues where
none exist.

The problem is that I understand virtual inheritance, and know
what is possible, and what isn't.
Back at you.

Except that I can prove my statements. Both by example and by
formal proof.
You know damn well what the context is here,

But you apparently don't.
and you know damn
well that Stroustrup and others have made a big deal of the
supposed fact that the C++ standard library *provides* tools,
but only as one choice. That they are explicitly acknowledged
to be not perfect for everything.

Yes. And I know that the reason offsetof was added to the C
standard, and the only reason, was because it wasn't
implementable in the language. There are good arguments why
things like vector (or strcpy in C) should be implementable
within the constraints of the language, and that's what
Stroustrup was talking about. But that's not all of the
library, and other parts (some basic I/O, memory management,
threading, etc.) are in the library largely because they can't
be implemented in the standard language. That's the context of
offsetof.
There is nothing about a container library that inherently
requires you to look outside of the language for the necessary
tools. If C++ cannot allow programmers to develop containers
without requiring non-standard features, it's a joke.

But that's a different context than offsetof. As far as I know,
none of the implementations of any of the standard containers in
C++ use any non-standard language features. (You can easily
look at the sources for g++, and determine yourself. For that
matter, because they are templates, and most compilers don't
implement export, you can generally look at the sources for any
of the implementations. If you find something non-standard, I'd
be interested in hearing about it.)

Part of the reason they can do this, of course, is that there
are lower level library functions offering access to behavior
that can't be implemented in the standard language---std::vector
uses an allocator which by default uses operator new() which
typically uses malloc. Which can't be written in standard C++,
which is why malloc is in the library.
Because without it, C++ is not fit for purpose, period.

Because you seem to be the only person who needs this
functionality, period. Everyone else implements component
libraries, even very low level component libraries, without it.
Rubbish, but beside the point.
If you explicitly encourage people to bring C code and
skillsets into C++, you cannot complain when they do so.

There's nothing "skill" in C code which uses offsetof. It was
added on a whim, not because it serves any useful purpose. (I
was able to implement a complete standard C library without it.)

[...]
I was asking for rationale as well, IIRC, but only if you know
it. I'm not holding you responsible except to the extent that
you appear to be complicit ;-)

I regret that there's no rationale available as well. (The C
committee did publish one, after C90.) But no one was there who
was willing to invest the necessary time. I wasn't ever active
on library issues; my "specialty" was (and is) basic language
issues.

With regards to C, you might be interested in the rationale
concerning offsetof: http://www.quut.com/c/rat/d1.html#4-1-5.
As I stated above, it is there to provide a portable means of
doing something that can't be done portably otherwise. As for
the "usefulness" they describe, pointers to members work just as
well, but in practice, I've never found it at all useful (and
I've written a lot of code for the context they describe:
interfacing a data base).

(I will acknowledge that it might be useful in implementing a
garbage collector, as they describe. I've generally used other
techniques, however.)
A *STANDARD* technique for moving to C++ is to wrap old C code in
templates or other adaptors, with minimal rewriting - which you
clearly know. As you say...

So standard that it doesn't work.
So it is of course blatantly obvious that people will use
templates with old C libraries.

And? Where is the problem. I can instantiate my templates over
existing C struct's without a problem.
This is trivial.
I need to reference a field in a struct (not a particular
instance). I control the definition of the struct, but some
fields take types that are template parameters (and can
therefore be a source of non-PODness) In some cases, these are
the fields I need to reference - but I don't need to reference
(or even know about) members within those template-parameter
types.

Why? That sounds like a torturous solution to a problem I can't
see.
My template is a thin wrapper around non-typesafe data-driven
code. The field-reference needs to be stored as an
initialised value in a static data block - a bit like a
closure.
Doing this with member pointers seems to cause compilers to
choke - they don't want to treat the member pointer as a
constant expression for whatever reason each particular
compiler comes up with, that reason varying from compiler to
compiler depending on the compromises they made with member
pointer implementation.

It would be interesting to see the code which causes the
compiler to choke with member pointers. I have instantiated
templates using pointer to member functions, with no problems.
And as you say, pointer to member syntax is not simple, so
there's a distinct possibility that you got something wrong
there.
Hence offsetof, which is a simple, easy to use way around this
issue and - once you're confident of your access functions -
perfectly safe too.
At least until someone decides to restrict it.

There was no decision to restrict it; it's always been
restricted. There was no one who thought it worthwhile to do
the work necessary to loosen the restrictions.
*Maybe* compilers are better at handling member pointers now,
but not in my experience as of yet (bare in mind that I've
just scratched the surface with GCC - other than that my most
recent compilers are VC++ 2003 and Borland C++ 5.02) and in
any case they certainly weren't working when I was writing the
initial code for these containers .

It's well known (and I beleive, even documented somewhere) that
VC++ requires the -vmg option for pointers to member functions
(and possibly pointer to member data) to work correctly. I've
used pointers to member functions with g++ since 2.31.x, and
never had any problems with them; I've instantiated templates
with them since 2.95.2.
Can you define the rules in which casting from one member
pointer type to another is safe, independent of any one
compiler? I'll bet you can't because these casts are
explicitly undefined.

Can you find a case where one would reasonable want to cast from
one member pointer type to another? (There are safe casts,
which can be done with static_cast. And this is fairly well
defined in the standard.)
Empty exception specifications are a special case which has
value, but that's not a justification for the full exception
specification part of the language. Sometimes, extending and
generalizing a good idea is a bad idea.

It's a problem when you innovate. It's hard to know in advance
what will or will not be needed. On the whole, the C++
committee seems to have gotten it better than most other
languages.
By your own argument, people have used it in some pretty
important libraries in C, which have now become C++ libraries.

Name one.
Ergo it is used in both C and C++. In standard library
implementations, no less.

I've never seen it. And I've implemented a complete C standard
library (a long time ago).
 
J

James Kanze

On Wed, 15 Oct 2008 16:30:54 +1300, Ian Collins
The standard has already been quoted at me, but read James'
point that I was replying too - this isn't about the standard,
it's about all the compilers he knows and what he thinks is
possible.
I challenge you. First, define a class using *ANY* standard
C++ features you please - multiple inheritance and virtual
inheritance included. Lets call this class TEST.
Now, create two instances of TEST. Don't care where you
instantiate so long as you aren't using any further
inheritance - global, local, normal member, static member,
anything.

You've suddenly introduced some new, unrealistic constraints.
Placement new it if you think that'll make a difference. Just
make sure you don't instance any derived classes - both must
be instances of the exact same class, ie TEST.
Now, show me a compiler - *ANY* compiler - that uses different
memory layouts for those two instances.
Basic science. The easiest way to prove that instances of a
single class can be arranged differently in different cases is
to provide an example, and I'm only asking for one.

I gave one in another posting. You've just said above (for the
first time) that you're not interested in that case. So
offsetof can be made to work, except when it can't.

The standard can't be based on such things. If the standard
says it works, then it has to work.
You won't find one. The layout of the class isn't dynamic.

The layout is dynamic. It depends on the context where the
class is used. You can't get around that by saying you don't
want to consider such contexts.
It may not be the same as the layout of any classes that
inherit from it, but that's beside the point. Even multiple
inheritance would break offsets if you're looking at derived
classes.

Not really. Given a class D, which derives virtually from a
class B, the offsets of elements inherited from B depends on how
D is being used---practically, it depends on which constructor
is called (in g++'s implementation), or which hidden argument is
passed to the constructor (in some other implementations I've
used).
Can you imagine what it would be like if one instance of a
class was arranged differently to another instance of that
exact same class?

I can not only imagine it, I've experienced it.
Can you imagine any vaguely coherent reason why a
compiler-writer would choose to introduce pointless
nondeterminism like this?

It's not nondeterminism, but it does depend on the context in
which the class is used. Given the arguments to offsetof, the
compiler does not have enough information to determine that
context.
 
J

James Kanze

Not quite *that* tight, but 'live' is questionable anyway.
That's not the price I saw for the standard (or the one James
quoted).

I didn't quote an exact price, because I didn't remember it.
But I do recognize that if you don't have a regular job, even
$18 can be a lot. (On the other hand, if you know C++, regular
jobs are pretty easy to come by, at least here in western
Europe. Maybe not always the best jobs in the world, but they
still beat unemployment benefits.)
If that price is available, next problem is no credit card. I
refuse to get one so long as I'm on benefits for obvious
reasons.
template<typename T>
struct This_May_Not_Be_POD
{
T Because_This_May_Not_Be_POD;
};
That's the whole point.

But that' not C; it's C++. And how is it relevant to offsetof?
 
S

Stephen Horne

You must be reading the wrong textbooks (or you don't understand
virtual inheritance), since it's provably impossible to do so.
And it's simple to try:
struct VB
....

struct M : virtual VB
....

struct D : M
{
int d ;
} ;
....

M v1 ;
v1.f( std::cout ) ;
D v2 ;
v2.f( std::cout ) ;
return 0 ;
}

I get different values for the two variables with every compiler
I try.

What this proves is that you didn't read my post. You haven't
instantiated two instances of the same class - you have instantiated
two instances of *TWO* *DIFFERENT* *CLASSES*.

Given all your insistence on pedantic language, how can you not notice
that point?

The class M uses virtual inheritance, but it's not a dynamic entity in
itself. It's not a run-time entity at all. It has one layout. It isn't
the same layout that is used for D, even for those components that are
inherited from M, but that's what you get for using virtual
inheritance. As I pointed out elsewhere, even multiple inheritance
breaks offsetof if thats what you're dealing with.

This issue has NOTHING to do with applications which take the
following form...

template<typename T>
struct Node
{
T field_within_node;
};

....

x = offsetof (Node<M>, field_within_node);

Unless you're stupid enough to think the offset also applies to
Except that I can prove my statements. Both by example and by
formal proof.

But primarily by failing to read before you reply and obsessing on an
irrelevant issue, which invalidates both so-called proofs.

If you can't read what I post before replying (or is it that you can't
admit to a mistake?), I see no point in reading on.
 
S

Stephen Horne

You've suddenly introduced some new, unrealistic constraints.

How so? In my container library, why would some other code be creating
nodes that inherit my private node type? That would be absurd.

These are the exact constraints I described from the start.

The offsetof is used to pick out the positions of certain fields in a
struct that I control, and placed in a closure-like data block, so
that data-driven non-typesafe code can find those fields. The struct
is defined as a private detail in a thin template wrapper.

Nodes are created. Nodes are accessed. Nodes are modified. Nodes are
destroyed. For any one wrapper class, they are all the same damn node
type - or at worst, minor variants with a shared header.

The node may be non-POD because the type specified by the application
as a template parameter for the contained data may be non-POD. This
*should* be completely irrelevant to offsetof.

Do I need to describe this again?
I gave one in another posting. You've just said above (for the
first time) that you're not interested in that case.

Crap - you just didn't read it properly.
The standard can't be based on such things. If the standard
says it works, then it has to work.


The layout is dynamic. It depends on the context where the
class is used. You can't get around that by saying you don't
want to consider such contexts.

class M isn't class D - they are different classes, irrespective of
the fact that one inherits the other. The layout for either one is
fixed.

As for not considering your irrelevant contexts, what the hell do you
expect. Inheritance has nothing to do with offsetof. To offsetof, any
struct or class is just itself - not a representative of a family.
Just as it always was.

Why the hell should I consider your invented fantasy issues?

Of course if someone is confusing the term "offset" with "member"...

Let me give you a clue. The word offset refers to the layout of the
struct/class. That is *all* it refers to. Any assumptions about that
offset mapping to any particular field in some other struct are
obviously the programmers responsibility, just as they always were,
and I'm not making *ANY* such assumptions. Inheritance would be just
another way to define that some other struct, but no-one gets the
chance to inherit the thing anyway. Any inheritance issues are purely
restricted to fields that takes application specified types, and
frankly should be none of the containers business.

The situation WRT the data structure node is - or at least should be -
exactly the same as it always was, irrespective of non-PODness
propogating up from member field to node struct.
It's not nondeterminism, but it does depend on the context in
which the class is used. Given the arguments to offsetof, the
compiler does not have enough information to determine that
context.

No it doesn't, because we are talking about a field within a known
struct, not within an instance of some unknown dynamically-accessed
struct. We always were right from the start. Its all we *could* have
been talking about, since offsetof doesn't know *ANYTHING* about
instances at all - it only ever sees types and field-names.

I only need offsetof to do the basic job that offsetof always did. I
don't need all the overengineered crap that's built into member
pointers, and neither does anyone else. If they had worked when I had
needed them I would have used them anyway, but they didn't.

All I require of offsetof is what it was always meant to do - give me
the offset of a known visible field within the fixed layout of a known
struct. The only "new" C++-specific thing is that the struct might
happen to have non-POD fields (due to app-specified types from
template parameters), and therefore the struct as a whole might happen
to be non-POD for that (and only that) reason.

In practice, of course, it should be perfectly possible to define my
node structs using multiple and virtual inheritance if I feel like it.
It makes no difference in principle - offsetof is still looking for a
known visible field in a known struct with a fixed layout. I wouldn't
*assume* it's possible because I know how the traditional macro form
worked.

But even for that, lets face it - most people would call virtual
inheritance a niche tool at best, and possibly another failed
experiment. What was done is to break offsetof for *all* cases of
non-POD however it arises, just to support virtual inheritance without
tweaking the offsetof implementation or even just stating "not if the
type inherits any virtual base, directly or indirectly" which took me
all of five seconds to write.

By the way, this "never used" offsetof is scattered throughout the
Microsoft libraries like confetti. Also, I popped over to
http://www.koders.com/, but I figured I didn't much feel like
searching through the 1,133 results - on a quick skim, some obviously
aren't genuine uses, but some equally obviously are. That's for C++,
not C.

Genuine uses occur in applications like Blender, in framework code
such as some marshalling stuff, in Boost and more.

Seems like offsetof is used. Not a huge amount of course - but any
"it's not needed because it's not used" argument is pure BS.

Oh, and that Boost example is a container. bidirectional_map to be
specific. And guess what - the offsetof parameter is a type that's
dependent on template parameters, which could easily be non-POD.

Well, I say "that Boost example", but there are several other examples
in Boost. Just pop over to Koders and do a search.

In other words Boost is doing exactly what I do. Wow. Boost
contributors doing precisely the same "no-one does that" thing that I
do. What a shock.


What the hell. You'll never admit to being wrong anyway, so what's the
point.

*PLONK*
 
S

Stephen Horne

I didn't quote an exact price, because I didn't remember it.
But I do recognize that if you don't have a regular job, even
$18 can be a lot. (On the other hand, if you know C++, regular
jobs are pretty easy to come by, at least here in western
Europe. Maybe not always the best jobs in the world, but they
still beat unemployment benefits.)

That's good - when you can cope with employment. It doesn't help much
when you have a disability that means simply seeing someones face can
trigger an autonomic stress response, simply hearing someones voice
can trigger a stress response, and so on. It doesn't help when that
stress response persists for certainly hours, potentially days, making
any regular sleep and waking pattern impossible.

Aspergers is a disability. Despite what some people think, it doesn't
mean I just don't like people much and don't get invited to parties.
It is a neurologically based disorder with consequences that might
seem trivial in the short term, but the long term repercussions of all
the stress include further brain damage that further deregulates the
stress response and so on.

In short, the Disney attitude dont-give-up-hope crap may be
well-intentioned, but it can still amount to abuse, pushing people
into situations where they end up even more disabled due to the damage
caused by sustained stress.


BTW - I'm not offended by what you said - no reason you should know
this stuff - even most autistics don't know this stuff, and I'm
starting to suspect the experts don't want to know because it would
upset parents, teachers, etc. Anyway, it's my problem, not yours -
just telling it as it is.


What I *want* to do is develop my own projects on my own schedule at
home, self employed. Not working out that way, partly because I can't
see how to make it work. Programming? yes. Target a complete
application to a potential market? Harder - my interests tend toward
internals - but if I have to. But the whole business? - really can't
see that working at all.

I mean, can you imagine my support e-mails? ;-)

Also, then there's the whole
benefits-cancelled-then-the-business-goes-tits-up thing. It took the
best part of a year to get through that crap last time around. It's
not easy when you're too sick to go through the process that proves
that you're sick - but only in phases so they don't really see it.

But that' not C; it's C++. And how is it relevant to offsetof?

It is very relevant when you take the offset of the field
Because_This_May_Not_Be_POD - remembering that this is a simplified
illustrative example.

Boost has code that uses offsetof, including a container that does
exactly this - except that its This_May_Not_Be_POD struct is actually
std::pair.


BTW - The *PLONK* stands, as soon as I set the filter up. After all,
we're both probably better off.
 
M

Martin Eisenberg

Stephen said:
That's good - when you can cope with employment. It doesn't help
much when you have a disability that means simply seeing
someones face can trigger an autonomic stress response, simply
hearing someones voice can trigger a stress response, and so on.
It doesn't help when that stress response persists for certainly
hours, potentially days, making any regular sleep and waking
pattern impossible.

Do you practice a stress-control technique? Autogenic Training and
various kinds of meditation can quite effectively help tame
the autonomic response. And don't think they're only of use to
neurotypicals.

Anyway, there's a software house in Sweden that specifically seeks
ADS sufferers and accomodates them with remote working etc. I can't
manage to seek them out now but I'll ask my source again. Or perhaps
someone else knows who I mean.


Martin
 
J

James Kanze

How so? In my container library, why would some other code be
creating nodes that inherit my private node type? That would
be absurd.

Who cares about what your container library might do? A
container library has no need of offsetof. We're talking about
why offsetof is not defined and not implementable in the general
case. And in the general case, you have to handle base classes
correctly.
These are the exact constraints I described from the start.

You never described any real constraints. The fact remains that
they are artificial constraints.
class M isn't class D - they are different classes,
irrespective of the fact that one inherits the other.

But the existance of a class M doesn't mean that class D ceases
to exist. And either offsetof( D, x ) returns a correct result,
constant and for all instances of D, or it can't be supported.
The layout for either one is fixed.

The layout of M isn't fixed. It varies depending on how M is
used.
As for not considering your irrelevant contexts, what the hell
do you expect. Inheritance has nothing to do with offsetof.

Agreed. The committee didn't want to open up that hornets'
nest, so they restricted offsetof to PODS. And a PODS cannot
inherit, much less virtually.
To offsetof, any struct or class is just itself - not a
representative of a family. Just as it always was.
Why the hell should I consider your invented fantasy issues?

Because they're real issues, and it's necessary to address them
if you want to support offsetof for non-PODS.
Of course if someone is confusing the term "offset" with
"member"...
Let me give you a clue. The word offset refers to the layout
of the struct/class.

And a class which derives from another class virtually doesn't
have a fixed layout.
No it doesn't, because we are talking about a field within a
known struct, not within an instance of some unknown
dynamically-accessed struct.

Exactly. We're talking about a field in M. Whose position
changes depending on how you use M.
We always were right from the start. Its all we *could* have
been talking about, since offsetof doesn't know *ANYTHING*
about instances at all - it only ever sees types and
field-names.

Which is why it is restricted to PODS, which do have constant
offsets, known to the compiler.

[...]
But even for that, lets face it - most people would call
virtual inheritance a niche tool at best,

It's widely used, and vitally necessary for many things.
 
J

James Kanze

What this proves is that you didn't read my post.

What this proves is what I said it proves. That sizeof is not
implementable for certain types.
You haven't instantiated two instances of the same class - you
have instantiated two instances of *TWO* *DIFFERENT*
*CLASSES*.

Do you know any C++ at all? I've definitly got two instances of
M; one in one context, and one that isn't.
Given all your insistence on pedantic language, how can you
not notice that point?

Did you notice that there is an M object in the D? Do you
understand what is meant by a type?
The class M uses virtual inheritance, but it's not a dynamic
entity in itself. It's not a run-time entity at all. It has
one layout.

Which is? It quite obviously has two different layouts in my
code above, depending on whether it is a base class of D or not.
It isn't the same layout that is used for D, even for those
components that are inherited from M, but that's what you get
for using virtual inheritance. As I pointed out elsewhere,
even multiple inheritance breaks offsetof if thats what you're
dealing with.

Not at this level. Modulo access issues and possible
ambiguities, offsetof could be well defined for multiple
inheritance, as long as no virtual inheritance is involved.
This issue has NOTHING to do with applications which take the
following form...

Whether offsetof is implementable for non PODS has nothing to do
with any application. It's a matter of principle: either the
offset is fixed, or it's not. In the case of C++, it's not, at
least when virtual inheritance is involved.
Unless you're stupid enough to think the offset also applies
to instances of Node<D> which is a DIFFERENT TYPE, just as D
is a DIFFERENT TYPE to M.
But primarily by failing to read before you reply and
obsessing on an irrelevant issue, which invalidates both
so-called proofs.
If you can't read what I post before replying (or is it that
you can't admit to a mistake?), I see no point in reading on.

In other words, you've lost the argument, so you're taking your
ball and going home.

I'd suggest you actually learn C++ before trying to criticize
it.
 
J

James Kanze

That's good - when you can cope with employment. It doesn't
help much when you have a disability that means simply seeing
someones face can trigger an autonomic stress response, simply
hearing someones voice can trigger a stress response, and so
on. It doesn't help when that stress response persists for
certainly hours, potentially days, making any regular sleep
and waking pattern impossible.

That's a serious disability, and if it is really that bad, it
pretty much means that you need to consider a different
profession. Programming is a team activity; you can't develop
good programs without working with others, and communicating
with them. Face to face and in writing.
Aspergers is a disability.

I won't argue with that. Although I'm not familiar with this
particular disability. There are lots of different types of
disabilities, and some of the disqualify the person for some
particular types of employ---you don't see many blind taxi
drivers, for example, and that's not because of anything I'd
consider discrimination against the blind. If you're going to
work in programming, not being able to meet and discuss things
with your collegues is a disqualifying disability, whatever its
reasons may be.

[...]
In short, the Disney attitude dont-give-up-hope crap may be
well-intentioned, but it can still amount to abuse, pushing
people into situations where they end up even more disabled
due to the damage caused by sustained stress.

Well, I suspect that there are some cases where you do have to
give up hope. I once had a blind friend who wanted to be a race
car driver. Realistically...

There are, of course, a lot of other things one can do.
BTW - I'm not offended by what you said - no reason you should
know this stuff - even most autistics don't know this stuff,
and I'm starting to suspect the experts don't want to know
because it would upset parents, teachers, etc. Anyway, it's my
problem, not yours - just telling it as it is.
What I *want* to do is develop my own projects on my own
schedule at home, self employed. Not working out that way,
partly because I can't see how to make it work. Programming?
yes. Target a complete application to a potential market?
Harder - my interests tend toward internals - but if I have
to. But the whole business? - really can't see that working at
all.
I mean, can you imagine my support e-mails? ;-)

All of us have our limits; maybe not as serious as yours, but I
tend to avoid support work as well; it doesn't fit me.
It is very relevant when you take the offset of the field
Because_This_May_Not_Be_POD - remembering that this is a
simplified illustrative example.

But the purpose of having offsetof in C++ is only backwards
compatibility with C. For all of the known uses of offsetof to
me, C++ has better alternatives.
 
S

Stephen Horne

Do you practice a stress-control technique? Autogenic Training and
various kinds of meditation can quite effectively help tame
the autonomic response. And don't think they're only of use to
neurotypicals.

Those techniques depend on the link back from the prefrontal cortex to
the amygdala being intact - the link that switches off unnecessary
stress reactions. It's a fragile link. Both the amygdala and the
prefrontal cortex are known damaged in autistic spectrum disorders.

In principle, aromatherapy is about the most likely option to work.
The senses of smell and taste are processed directly in the amygdala,
which is the main autonomic stress response trigger. There's no
guarantee, though, that any smell would make any difference and all I
can say for certain is that I like citrus smells.

The point is that stress control techniques only work if I'm not
really all that stressed anyway. Bear in mind that my really good day
is probably comparable to a normal persons really bad day.

I obsessed with trying to fix myself for decades before finding out
what the problem is. I've tried plenty. What seemed to work in a sense
basically turned out to be a flavor of cognitive behavioural therapy,
but all it was really doing was training me to take on more and more
stress.

The stress response isn't all negative emotions. Think adrenaline
junkie thrills, excitement and mania. Irrespective of whether it feels
good or bad, your brain and body are still running beyond their
sustainable limits and they are still damaging themselves further, and
you are still going to crash and burn. And the next burnout will be
faster and more severe, and so on.
Anyway, there's a software house in Sweden that specifically seeks
ADS sufferers and accomodates them with remote working etc. I can't
manage to seek them out now but I'll ask my source again. Or perhaps
someone else knows who I mean.

Wouldn't they want people who can speak Swedish?
 
S

Stephen Horne

As Stephen is not so prone to provide compilable code samples

The following compilable code sample has been provided many times...

template<class T>
struct whatever
{
T field;
};

....

x = offsetof(whatever, field);

For full compilable source, we're talking 7 separate source files with
sizes ranging from about 1000 to about 2500 lines each. Therefore,
descriptions and simplified examples.

I have also provided a reference to a Boost source file that does
basically what I do. Go to www.koders.com and you'll find other
examples. It's not everyday stuff, any more than member pointers or
virtual inheritance, but it's used.


Single inheritance as in your example won't break offsetof in
practice, but IMO it's not the right solution for this.

If any Derived uses Multiple inheritance or virtual inheritance, even
indirectly, offsetof definitely breaks. On some compilers, having
virtual inheritance will cause offsetof to crash immediately (or at
least generate nonsense), since the traditional macro expansion would
end up trying to read the virtual table of a non-existent instance.

OTOH, if Derived is no worse than single inheritance, having fields
that have multiple-inheritance or virtual-inheritance types won't
break it - in practice only - no guarantees from the standard since
your classes are non-POD (even without the inheritance issues from
above).

However, because this depends on users following a rule that the
compiler won't enforce for you, its unsafe. My experience is that
people will forget about that rule.

I'll assume you have good reasons for not making param1 a parameter of
Run.

I'd recommend using pure access functions declared in Base to get at
param1. The virtual call overhead *might* be a problem for you, but
don't optimise until you're sure you need to.

Even if you need to optimise, there are much safer ways to do it. e.g.
You could provide an pure access function in Base that returns a
reference or pointer to the variable within the instance. Then you can
update the buffer as often as you like with minimal cost, so long as
the instance stays put. If there's any possibility that the user might
put the buffer somewhere outside the instance, a lock-and-release
approach might be worthwhile to at least make it explicit that the
buffer is meant to stay put and for how long.

That gives you something like...

BUFFER buffer = obj->lock_buffer ();
// I'll assume exception-for-fail - why nullcheck when most
// implementations will be trivial and infallible.

while (...)
{
*buffer = whatever;
obj->Run ();
}

obj->release_buffer (buffer);

Even if you use a member pointer, the basic principle of converting to
a simple pointer before entering an inner loop still makes sense - and
one advantage if member pointers work for you is that the compiler
will probably do that optimisation for you.

But access functions are the basic workhorse for doing this kind of
thing - member pointers cause too many problems to be practical in my
experience, and offsetof is unsafe if the type of the instance is a
run-time variable.
 
J

James Kanze

Stephen Horne <[email protected]> kirjutas:
As Stephen is not so prone to provide compilable code samples,

Stephen seems mainly prone to insulting the committee because
they didn't design the language exactly according to his
desires.

The problem is simple: C++ inherited offsetof from C. When
<cstddef> was being defined, the problem of defining what
offsetof meant in C++ (with class types, rather than struct
types) had to be addressed. The simplest solution (in terms of
actual work) was just to limit it to what is basically C: PODS.
Obviously, other solutions are possible, but some restrictions
are necessary. Clearly defining those restrictions is
additional work. Apparently, no one at the time felt it worth
the effort---either they didn't see any important use of
offsetof, or they felt that there were more important things to
do, or whatever. The committee depends on volontary effort, and
no one volonteered to extend offsetof to non-POD types.

All of the rest is really just useless discussion. I don't
particularly see much use of offsetof, and I've written a lot of
low level code. Which explains why I didn't volonteer to do the
work of extending it. The fact that many others working in the
committee apparently felt like me is the real reason why
offsetof isn't defined for non PODS. (The fact that many others
working in the committee -- most of whom are considerably more
competent than I am -- apparently felt like me reassures me.
All too often, I'm in disagreement with a large part of the
committee, which makes me wonder.)
 
M

Martin Eisenberg

Stephen said:
Those techniques depend on the link back from the prefrontal
cortex to the amygdala being intact - the link that switches off
unnecessary stress reactions.
The point is that stress control techniques only work if I'm not
really all that stressed anyway.

Of course if you tried it without benefit I can't argue with that.
But I do think that "intact" is too strong a constraint -- it's not a
one-way street, and neither is acute "firefighting" the main point of
practice.

But let's not dwell off topic, I mainly just thought someone might
know that company.
Wouldn't they want people who can speak Swedish?

No. My friend's still digging, though.


Martin
 
M

Martin Eisenberg

Martin said:
Anyway, there's a software house in Sweden that specifically
seeks ASD sufferers and accomodates them with remote working
etc.

In case anyone's interested, the name is Specialisterne.


Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top