Wednesday, July 5, 2017

Digest for comp.lang.c++@googlegroups.com - 20 updates in 4 topics

woodbrian77@gmail.com: Jul 04 06:28PM -0700

On Monday, July 3, 2017 at 2:58:54 PM UTC-5, Öö Tiib wrote:
> Usually automatic variable or direct data member, 'std::optional',
> 'std::array', 'std::vector' or 'std::make_unique' are better, safer and
> more efficient to use at that spot.
 
I'm looking forward to being able to write:
 
::std::unique_ptr request{new cmw_request(recbuf)};
 
rather than:
 
auto request=::std::make_unique<cmw_request>(recbuf);
 
in C++ 2017. Support for this isn't widely available
yet, though, from what I can tell.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
https://github.com/Ebenezer-group/onwards
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 05 04:14AM +0200


> auto request=::std::make_unique<cmw_request>(recbuf);
 
> in C++ 2017. Support for this isn't widely available
> yet, though, from what I can tell.
 
You can write that first declaration today, and you could from and
including C++11.
 
Using `make_unique` only matters when there are two or more `unique_ptr`
initializations in the same expression, since then a non-smart compiler
might let the `new` expressions be evaluated before the `unique_ptr`
initializations, and then what if the second `new` fails? Leak. Ouch.
 
As I understand it C++17 will make that use of `unique_ptr` unnecessary,
by constraining the evaluation order slightly.
 
 
Cheers!,
 
- Alf
woodbrian77@gmail.com: Jul 04 10:29PM -0700

On Tuesday, July 4, 2017 at 9:14:26 PM UTC-5, Alf P. Steinbach wrote:
> > yet, though, from what I can tell.
 
> You can write that first declaration today, and you could from and
> including C++11.
 
I have the above two lines here:
https://github.com/Ebenezer-group/onwards/blob/master/tiers/cmwAmbassador.cc
 
at lines 270 and 271. One of the lines is commented
out because I don't know of a compiler that accepts it
right now:
 
//::std::unique_ptr request{new cmw_request(recbuf)};
 
This thread is related:
https://groups.google.com/forum/#!topic/comp.lang.c++/m43-E2_msOw
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 05 03:37PM +0200


> //::std::unique_ptr request{new cmw_request(recbuf)};
 
> This thread is related:
> https://groups.google.com/forum/#!topic/comp.lang.c++/m43-E2_msOw
 
I failed to see that there isn't any template argument for `unique_ptr`.
 
I think, from the reference to old discussion, that you're envisioning
constructor template argument deduction, as in <url:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4471.html>.
 
From what I understand of that paper they intend that the expression
`unique_ptr{ new T }` should be well-defined, deduced as `unique_ptr<T>{
new T }. But that wouldn't allow you to omit template argument in the
type in a declaration. You could use `auto` though.
 
* * *
 
The paper starts with the following example, which I've taken the
liberty of reformatting to more readable for me:
 
 
vector<int> vi1 = { 0, 1, 1, 2, 3, 5, 8 };
 
vector<int> vi2;
 
template< class Func > std::mutex m;
 
unique_lock<std::mutex> ul( m, std::defer_lock );
 
class Foo()
{
public:
Foo( Func f ) : func( f ) {}
void operator()(int i) { os << "Calling with " << i << endl; f(i); }
private:
Func func;
mutex mtx;
};
 
 
I /think/ that the author intended for the class to be a template,
starting with `template< class Func >`.
 
 
Cheers!,
 
- Alf
woodbrian77@gmail.com: Jul 05 12:29PM -0700

On Wednesday, July 5, 2017 at 8:38:15 AM UTC-5, Alf P. Steinbach wrote:
> `unique_ptr{ new T }` should be well-defined, deduced as `unique_ptr<T>{
> new T }. But that wouldn't allow you to omit template argument in the
> type in a declaration. You could use `auto` though.
 
Is this what you mean by using auto:
 
::std::unique_ptr<auto> { new T}
 
? Several months ago I applied a patch from professor
Spertus to a version of g++. After doing so I was able
to compile the line as I've written it here previously:
 
:std::unique_ptr request{new cmw_request(recbuf)};
 
. Professor Spertus saw my code and didn't say, "Hey,
you need to add auto ..."
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
woodbrian77@gmail.com: Jul 04 07:41PM -0700

There's const_string:
http://conststring.sourceforge.net/
 
and fix_str:
https://www.codeproject.com/articles/12024/fix-str-an-almost-immutable-string-class-in-c
 
I'm not sure why something like this hasn't been more popular,
so I decided to give it a shot also. Small string optimization
goes up to around 24 characters I think. I think this could be
helpful for cases that are bigger than that.
 
Please let me know what you think about it. I may add some
assignment operators.
 
 
#pragma once
#include"ErrorWords.hh"
#include"marshalling_integer.hh"
#include"SendBuffer.hh"
#include<array>
#include<string_view>
#include<string.h>

namespace cmw{
 
template<int N>
class fixed_string{
int length;
::std::array<char,N> str;

public:
explicit fixed_string (char const* s):length(::strlen(s)){
if(length>N-1)throw failure("fixed_string ctor");
::strcpy(&str[0],s);
}
 

 explicit fixed_string (string_view s):length(s.length())){
if(length>N-1)throw failure("fixed_string ctor");
::strncpy(&str[0],s.data(),length);
str[length]='\0';
}
 
template<class R>
explicit fixed_string (ReceiveBuffer<R>&buf):length(
marshalling_integer(buf)()){
if(length>N-1)throw failure("fixed_string stream ctor");
buf.Give(&str[0],length);
str[length]='\0';
}
 

 void Marshal (SendBuffer& buf,bool=false)const{
marshalling_integer(length).Marshal(buf);
buf.Receive(&str[0],length);
}
 

 char const* c_str ()const {return &str[0];}
char operator[] (int index)const {return str[index];}
};

using fixed_string_60 = fixed_string<60>;
using fixed_string_120 = fixed_string<120>;
}
 
 
I haven't checked this in yet, but probably will over here:
https://github.com/Ebenezer-group/onwards
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jul 05 07:32AM +0200

> helpful for cases that are bigger than that.
 
> Please let me know what you think about it. I may add some
> assignment operators.
 
I never used any of the above. But I already used immutable string
classes in larger projects.
 
Well I think that strings of statically typed size are of little use
unless you intend to port very old code from Cobol or something similar.
 
On the other side /immutable/ strings /are/ very useful, especially in
multi-threaded environments because they are intrinsically thread-safe
for read operations.
 
But if you talk about immutable strings you need always talk about
/mutable/ string references, too. They are essential to use the
immutable strings. They provide the object lifetime management. And, of
course, they are /not/ intrinsically thread-safe.
Most of the time the programmer will deal with these string references
rather than the internal string behind the scenes.
 
Writing an immutable string class is straight forward. But writing a
reasonably smart, mutable wrapper around the string references /is/ an
advanced topic, at least if you include thread-safety with reasonable
performance.
 
The basic idea behind this concept is to keep any non-mutating
operations to the strings content constant time, including assignment
(of the references) and including thread-safe read and write of the
references.
In fact it can be implemented lock-free and even without CAS loops or
spin-locks. BTDT
 
If you have gone this way it opens the door to deduplication of string
values in memory and in memory database applications with rather high
performance. BTDT, too.
 
 
Marcel
peter koch <peter.koch.larsen@gmail.com>: Jul 05 02:01AM -0700

Den onsdag den 5. juli 2017 kl. 07.32.43 UTC+2 skrev Marcel Mueller:
> > helpful for cases that are bigger than that.
 
> Well I think that strings of statically typed size are of little use
> unless you intend to port very old code from Cobol or something similar.
 
Why? I guess it very much depends on your application area.
Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.
This enables me to verify my strings size at creation rather than when I need to serialise it (putting it on a display or sending it over a wire).
 
Internally, my size-limited strings are represented as a std::(w)string or as a boost::small_vector (if I remember the name correctly).
 
The same is the case for any array I use representing "external" data.
 
> multi-threaded environments because they are intrinsically thread-safe
> for read operations.
 
> Marcel
Certainly! Immutable and hopefully also constexpr so that I can manipulate them while compiling.
 
/Peter
Dombo <dombo@disposable.invalid>: Jul 05 08:06PM +0200

Op 05-Jul-17 om 7:32 schreef Marcel Mueller:
 
 
> If you have gone this way it opens the door to deduplication of string
> values in memory and in memory database applications with rather high
> performance. BTDT, too.
 
In many programming languages such as C#, Java and Python strings are
immutable, which is a very useful property indeed. It would be a nice if
standard library supplied a immutable string class of its own.
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jul 05 08:46PM +0200

On 05.07.17 11.01, peter koch wrote:
>> unless you intend to port very old code from Cobol or something similar.
 
> Why? I guess it very much depends on your application area.
> Personally, I have much use of strings with a static maximum size, using them whenever I program against an interface which defines maximum sizes for I/O.
 
A static *maximum* size is helpful, indeed.
But AFAICS the example always allocated the maximum size. This is big
waste of memory unless the limit is only a few bytes.
 
 
>> for read operations.
 
>> Marcel
> Certainly! Immutable and hopefully also constexpr so that I can manipulate them while compiling.
 
Well, this is an even more advanced topic, since the restrictions for
constexpr are quite tight. I don't think that a string class can have a
/runtime/ dynamic length and constexpr (factory) functions at the same
time, at least not with C++11.
 
I had a similar requirement years ago. I.e. neither the string class
constructors of program constants should invoke dynamic allocations at
program startup, nor a dynamic allocation and string copying should
happen every time the constant is accessed. In fact no copying of the
constant data should be done at all.
I ended up with a distinct class for this purpose. This one had the
string length in the type and used the internal data structures of the
'normal' string class in a way that prevented the deallocator from
running so it could bind to static storage rather than heap storage.
 
It should be possible to write a class for your requirements that is
compatible to the matching immutable string class.
 
 
Marcel
peter koch <peter.koch.larsen@gmail.com>: Jul 05 12:15PM -0700

Den onsdag den 5. juli 2017 kl. 20.46.28 UTC+2 skrev Marcel Mueller:
 
> A static *maximum* size is helpful, indeed.
> But AFAICS the example always allocated the maximum size. This is big
> waste of memory unless the limit is only a few bytes.
 
I do not know which example you are referring to. In my code, I simply choose between boost::container::static_vector and std::vector dependent on the maximum number of elements.
When max_size < threshold/sizeof(T), I choose the static vector. threshold is currently defined as sizeof(std::string) and this seems like a reasonable default, assuming the compiler-folks have taken their time to decide on a proper size for SSO.
 
For compile-time strings you want a newer compiler, at least C++14. And not Microsofts right now.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 05 01:40AM +0200

On 05-Jul-17 12:11 AM, Christiano wrote:
> {
> if (n==nullptr) return this;
> if (this==nullptr) return n;
 
Looks like a typo.
 
It could be a thinko from habit, though, because when Bjarne designed
the language it didn't have exceptions, so the way to signal
construction failure was to do `this = 0;`. So at that time, before
exceptions, the `this` pointer could certainly be 0.
 
As I recall we got exception around 1989-1991, the time of the ARM.
 
 
> paragraph 5.2.5/3 of the standard ISO/IEC 14882:2003(E)), calling any
> nonstatic method of any class through a null-pointer leads to undefined
> behavior. "
 
Right.
 
 
> But the ISO/IEC 14882:2003, § 5.2.5.3 says: If E1 has the type
> "pointer to class X," then the expression E1->E2 is converted to the
> equivalent form (*(E1)).E2;
 
There is an infamous note (notes are non-normative in ISO standards) in
C++14 §8.3.2/5 (or C++98 §8.3.2/4): "in particular, a null reference
cannot exist in a well-defined program, because the only way to create
such a reference would be to bind it to the "object" obtained by
indirection through a null pointer, which causes undefined behavior"
 
It's infamous because it /claims/ that the standard elsewhere prescribes
UB for *p when p is a null pointer, but there is no such wording.
 
Still, everyone agrees that it's UB to dereference a nullpointer, except
in a `typeid` expression, where you're guaranteed an exception in that case.
 
 
> of any class through a null-pointer leads to undefined behavior".
> And (*(E1)) being a lvalue when E1 is null is not a problem IF THE
> PROGRAMMER IS AWARE OF WHAT HE IS DOING.
 
The compiler is free to insert code that checks for nullpointer and if
so, plants some nasty NSA malware on your computer.
 
 
> What I'm trying to say is exactly:
 
> The "Comparing 'this' Pointer to Null as an undefined
> behavior" is a MYTH which is not based on Standard.
 
No, not a myth, but the standard has never been fixed. It /claims/, in
non-normative text, that it says, but it doesn't actually say. That this
state of affairs has lasted through three and now soon four revisions is
pretty weird, but presumably more important stuff's been fixed instead.
 
 
> You can see this myth in several websites:
> https://www.google.com/#q=this+null+c%2B%2B
 
> Following this reasoning, Stroustrup is correct,
 
No, that code is just a typo or thinko.
 
 
> g++ is correct [2], and Clang is correct [3].
 
Yes, UB means that they can do whatever. So I haven't even checked what
you cite that they do. Or don't.
 
 
> And the standard shouldn't forbid it because it has been used correctly
> for a long time without problems so that it would be much fairer to be
> interpreted as a technique.
 
It was used for a long time – before C++ got exceptions.
 
Which was roughly 10 years before the first standardization.
 
 
[snip]
 
Cheers & hth.,
 
- Alf
Christiano <christiano@engineer.com>: Jul 04 10:24PM -0300

On 07/04/17 20:40, Alf P. Steinbach wrote:
 
> Looks like a typo.
 
> It could be a thinko from habit, though, because when Bjarne designed the language it didn't have exceptions, so the way to signal construction
> failure was to do `this = 0;`. So at that time, before exceptions, the `this` pointer could certainly be 0.
 
It was not that, because after he says:
 
-------- excerpt begin ---------
Note that this has a specific meaning: it points to the object for which a member function is called. It does not point to any old object. The
compiler ensures that we do not change the value of this in a member function. For example:
 
struct S {
// . . .
void mutate(S* p)
{
this = p; // error: this is immutable
// . . .
}
};
------------excerpt end ----------
 
The Link * that the function returns is the first link from a doubly linked-list (with Gods[1] inside).
And if, for example:
Link *p = nullptr; // EMPTY LIST
p = p.insert(new Link{"Athena"}); // INSERTING ATHENA
 
It will work just because insert return the new Athena making it as the new element of the list.
 
I'm sure it was not a mistake.
 
> exist in a well-defined program, because the only way to create such a reference would be to bind it to the "object" obtained by indirection through a
> null pointer, which causes undefined behavior"
>> It's infamous because it /claims/ that the standard elsewhere prescribes UB for *p when p is a null pointer, but there is no such wording.
 
Exactly! There is no such wording. The difference here is:
 
✓ You and several peoples are saying that there should be such wording.
✓ I am saying that there should NOT be such wording.
 
And this note should be corrected because it doesn't consider situations where the dereference doesn't access data and so shouldn't cause UB.
The error here is to consider that all dereference implies data access.
 
Obviously, if you do:
int *a = nullptr;
*a = 10;
 
Of course, it is UB because the code above is obviously wrong. But the Stroustrup code, very interesting in my opinion, makes perfect sense.
 
A specification fails to encompass all possibilities at first, the use of language showed that in this particular topic it has failed to foresee some
possibilities, it is normal. So, in my opinion, it makes more sense to adapt the specification to reality than the reality to adapt to a possible and
vague interpretation of the specification, which would invalid very interesting codes like that stroustrup's code.
 
[1] Please, I am not promoting or disrespecting any religion, I am just following the example of the book which contain lists of ancient Greek and
Nordic gods.
Richard Damon <Richard@Damon-Family.org>: Jul 04 10:33PM -0400

On 7/4/17 6:11 PM, Christiano wrote:
 
> of any class through a null-pointer leads to undefined behavior".
> And (*(E1)) being a lvalue when E1 is null is not a problem IF THE
> PROGRAMMER IS AWARE OF WHAT HE IS DOING.
 
The problem is that the dereferencing of a null pointer is undefined
behavior, so you haven't escaped the problem. Yes, sometimes if you know
the implementation well enough, and are willing to take your chances it
won't change, sometimes you can get away with undefined behavior. That
doesn't make it reasonable to say the behavior shouldn't be undefined.
 
Part of the issue with this is that the implementation can (and
sometimes must) access hidden pieces of the object (like what is
typically called the vtable) to work with an object, and the function
might do so in its preamble as part of its standard operation (even if
it later might see it doesn't need to). AFAIK, the only object that
can't have this sort of data stored in them is what is called a POD
(Plain Ole Data) which are layout compatible with C code.
 
My memory is that early in the development of C++ there were cases where
you could end up with a null this, but well before it came to the first
standard this was dropped,
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jul 05 07:06AM +0200

On 05.07.17 03.24, Christiano wrote:
> p = p.insert(new Link{"Athena"}); // INSERTING ATHENA
 
> It will work just because insert return the new Athena making it as the
> new element of the list.
 
Invoking insert() on an object of type Link* won't compile.
 
p = p->insert(new Link{"Athena"}); // INSERTING ATHENA
might compile. But it is UB.
 
The latter might also work es expected. UB always included the case that
it works as expected. It is just not reliable.
 
 
> ✓ I am saying that there should NOT be such wording.
 
> And this note should be corrected because it doesn't consider situations
> where the dereference doesn't access data and so shouldn't cause UB.
 
This constraint is not sufficient.
E.g. if in the above example insert is virtual it will crash. Even when
the invoked method does not access any data.
So it will basically only be valid for POD structures. But this prevents
the constructor of Link to exist.
 
> *a = 10;
 
> Of course, it is UB because the code above is obviously wrong. But the
> Stroustrup code, very interesting in my opinion, makes perfect sense.
 
I have also written code which allows to invoke some simple functions on
a null object in very rare cases. But this code was never intended to be
portable.
A specific platform might always give further guarantees, shrinking the
area of UB.
 
> more sense to adapt the specification to reality than the reality to
> adapt to a possible and vague interpretation of the specification, which
> would invalid very interesting codes like that stroustrup's code.
 
Feel free to submit a draft.
 
 
Marcel
Christiano <christiano@engineer.com>: Jul 05 03:23AM -0300

On 07/05/17 02:06, Marcel Mueller wrote:
> On 05.07.17 03.24, Christiano wrote:
 
> Invoking insert() on an object of type Link* won't compile.
 
Correcting:
Link *p = nullptr; // EMPTY LIST
p = p->insert(new Link{"Athena"}); // INSERTING ATHENA
// p is pointing to Athena now.
// p-->[athena]
p = p->insert(new Link{"Odin"}); // INSERTING Odin
// p is pointing to Odin now.
// p-->[odin]<->[athena]
 
 
> This constraint is not sufficient.
> E.g. if in the above example insert is virtual it will crash. Even when the invoked method does not access any data.
 
Yes, it will crash because virtual methods necessarily need to access data (virtual table) which compose the class object. But this case would be a
wrong code. What is wrong with Stroustrup code? Nothing, because nonvirtual methods doesn't influence the object bytes. The Stroustrup's code is very
interesting. Why it should be UB when it is not? You are talking about a different case, the Insert is not virtual therefore
p->insert(new Link{"Athena"});
will not access any data from nullptr position (Insert will return on 2nd line).
 
> So it will basically only be valid for POD structures. But this prevents the constructor of Link to exist.
 
The stroustrup code works. The Link is defined as:
 
class Link {
public:
string value;
 
Link(const string& v, Link* p = nullptr, Link* s = nullptr)
: value{v}, prev{p}, succ{s} { }
 
Link* insert(Link* n) ; // insert n before this object
Link* add(Link* n) ; // insert n after this object
Link* erase() ; // remove this object from list
Link* find(const string& s); // find s in list
const Link* find(const string& s) const; // find s in const list (see §18.5.1)
 
Link* advance(int n) const; // move n positions in list
 
Link* next() const { return succ; }
Link* previous() const { return prev; }
private:
Link* prev;
Link* succ;
};
 
It is not a POD.
 
 
In C programming, it is common the following code:
 
struct X *a = NULL;
// ...
a = (struct X *) malloc(N*sizeof(*a)); // EQUIVALENT: a = (struct X *) malloc(N*sizeof(struct X));
 
See: sizeof(*a)
Does *a here cause UB? It will not cause UB... because sizeof(*a) actually doesn't need to access *a at all (it is a static operator).
 
Now, see again:
 
Link *p = nullptr; // EMPTY LIST
p = p->insert(new Link{"Athena"}); // INSERTING ATHENA
 
equivalent:
p = (*p).insert(new Link{"Athena"});
The same thing: when compiler is generating code, this line actually doesn't need to generate code that access *p at all, p can be anything, In any
architecture: MIPS, ARM, x86, Risc-V, SPARC, POWER, Microcontrollers whatever. In any Operating system: windows, macosx, linux, BSD, RTOS's whatever.
 
Therefore comparing "this" with "nullptr" should be recognized as a technique.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 05 05:12PM +0100

On 05/07/2017 07:23, Christiano wrote:
> Therefore comparing "this" with "nullptr" should be recognized as a
> technique.
 
Wrong. Dereferencing a null pointer is UB so 'this' should never by null
unless you are invoking UB.
 
/Flibble
peter koch <peter.koch.larsen@gmail.com>: Jul 05 10:59AM -0700

Den onsdag den 5. juli 2017 kl. 00.11.38 UTC+2 skrev Christiano:
> n–>succ = this; // this object comes after n
> if (prev) prev–>succ = n;
> n–>prev = prev; // this object's predecessor becomes
 
A conforming C++ compiler will know that this never can be null and will replace if (this == nullptr) with if (true). In fact clang gives this warning:
<source>:6:13: warning: 'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true [-Wtautological-undefined-compare]
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jul 05 08:19PM +0200

On 05.07.17 08.23, Christiano wrote:
>> when the invoked method does not access any data.
 
> Yes, it will crash because virtual methods necessarily need to access
> data (virtual table) which compose the class object.
 
The existence of the vtable pointer is already implementation defined.
Although this is quite common.
 
> p->insert(new Link{"Athena"});
> will not access any data from nullptr position (Insert will return on
> 2nd line).
 
Well, the standard simply does not require this kind of restriction for
implementers. Implementations /might/ access the object behind *this of
any non POD type for any implementation specific purpose. Not the
functions are the problem, but the existence of a constructor makes the
type non POD.
 
And AFAIK even for POD types this == nullptr is not well defined
behavior. Although it is likely to work since POD types should not
contain any additional internal data members.
 
On the other hand the code will also crash if inheritance comes into
play. In case of multiple inheritance the raw pointer value has to be
modified at explicit or implicit type conversions. This implies a
nullptr-check unless the compiler is sure that the raw pointer cannot be
nullptr. In fact the generated code for references and *this usually
just adds a constant while for pointer types a conditional expression is
generated. So in this case nullptr might be converted to some nonzero
value and the this == nullptr check will fail. Again UB.
 
>> So it will basically only be valid for POD structures. But this
>> prevents the constructor of Link to exist.
 
> The stroustrup code works.
 
You can't tell this. It works on some platforms, maybe on many. But to
tell that it always works (with a C++ compatible compiler) it must work
on any platform, including the ones that do not yet exist. You can't
prove that unless the code is standard conformant.
 
 
> The Link is defined as:
 
[...]
> It is not a POD.
 
Indeed.
 
 
 
> See: sizeof(*a)
> Does *a here cause UB? It will not cause UB... because sizeof(*a)
> actually doesn't need to access *a at all (it is a static operator).
 
Exactly. Neither sizeof nor typeof evaluate the expression.
 
> p = (*p).insert(new Link{"Athena"});
> The same thing: when compiler is generating code, this line actually
> doesn't need to generate code that access *p at all, p can be anything,
 
The invocation of insert() /might/ access *p.
 
 
> In any architecture: MIPS, ARM, x86, Risc-V, SPARC, POWER,
> Microcontrollers whatever. In any Operating system: windows, macosx,
> linux, BSD, RTOS's whatever.
 
Well, making assumptions on platforms based on statistics is risky.
E.g., I have worked on a platform where *(int*)0 might access a valid
memory address (inmos T80x).
 
> Therefore comparing "this" with "nullptr" should be recognized as a
> technique.
 
The standard might be enhanced in the way that this is well defined
behavior for POD types. For now it is not.
But I am in doubt that this will ever be defined for non POD types like
the Link class above.
 
 
Marcel
legalize+jeeves@mail.xmission.com (Richard): Jul 05 06:02PM

[Please do not mail me a copy of your followup]
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> spake the secret code
 
>stdlib - UTF8 console i/o in Windows, other crucial fixes, functional
>area headers
 
Seems useful, but unfortunately a name like "stdlib" is a really poor
name for this library IMO. It implies that this is somehow conencted
with the C++ Standard Library, as opposed to a user written layer on top.
 
Off the top of my head, names like "handylib", "alflib", or even
"alfabits" (pun on US cereal name) would all be better names for this
library.
 
Actually, now that I'm seeing on screen, I like alfabits :).
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: