Thursday, November 24, 2016

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

"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 24 04:56AM -0800

Psalm 100
 
http://biblehub.com/kjv/psalms/100.htm
 
Shout for Joy to the Lord, All You Lands!
 
1 {A Psalm of praise.} Make a joyful noise unto the LORD, all ye lands.
 
2 Serve the LORD with gladness: come before his presence with singing.
 
3 Know ye that the LORD he is God: it is he that hath made us, and not
we ourselves; we are his people, and the sheep of his pasture.
 
4 Enter into his gates with thanksgiving, and into his courts with
praise: be thankful unto him, and bless his name.
 
5 For the LORD is good; his mercy is everlasting; and his truth
endureth to all generations.
 
-----
There is love, peace, and joy in the house of the Lord, but only when
you keep your eyes focused on Him. If you begin looking around at the
things of the world, they will quickly pull you under. But when you
look up to Him, and keep looking up, there you find your peace, because
only there is your salvation.
 
Remember also ... Peter walked on water too, but only when he was
looking at the Lord!
 
http://biblehub.com/kjv/matthew/14.htm
 
28 And Peter answered him and said, Lord, if it be thou, bid me
come unto thee on the water.
29 And he said, Come. And when Peter was come down out of the ship,
he walked on the water, to go to Jesus.
30 But when he saw the wind boisterous, he was afraid; and beginning
to sink, he cried, saying, Lord, save me.
31 And immediately Jesus stretched forth his hand, and caught him,
and said unto him, O thou of little faith, wherefore didst thou
doubt?
32 And when they were come into the ship, the wind ceased.
33 Then they that were in the ship came and worshipped him, saying,
Of a truth thou art the Son of God.
 
Jesus will save your eternal soul, and give you eternal life. All you
have to do is trust and believe.
 
Best regards,
Rick C. Hodgin
JiiPee <no@notvalid.com>: Nov 24 12:36AM

Just cannot be sure what happens if I do the following:
 
class A
{
public:
void foo() {
delete this;
}
};
 
int main()
{
std::unique_ptr<A> b;
b.foo();
// (*) here: what is the state of b?
}
 
How does b know that its object is deleted? Can i use b normally after
(*) or is it in undefined state?
If I want to delete the object inside foo(), how should i do it so that
b is in good state, or is it even possible?
Is this a wrong way to use unique_ptr (so we should not delete object
inside its member variable)?
JiiPee <no@notvalid.com>: Nov 24 12:42AM

Sorry, should be like this in main:
std::unique_ptr<A> b = std::make_unique<A>();
b->foo();
 
 
On 24/11/2016 00:36, JiiPee wrote:
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 24 12:56AM

On Thu, 24 Nov 2016 00:36:37 +0000
> that b is in good state, or is it even possible?
> Is this a wrong way to use unique_ptr (so we should not delete object
> inside its member variable)?
 
b.foo() won't compile, and presumably you meant b->foo(). If so, yes,
you have it completely wrong. First you have not actually allocated
an A object, so b->foo will dereference a null pointer and the program
will terminate. Secondly even if you had allocated an A object to be
managed by b, your code would cause a double delete, memory corruption
and woe, because b->foo() would delete the A object, and b would try
to do the same when it goes out of scope.
 
You need to look up some documentation on unique_ptr. They are very
simple things - it should take you about 10 minutes to work it out.
You could do what you want by releasing the unique_ptr when you call
A::foo() (see std::unique_ptr::release()), but having an object know
what object manages it defeats the purpose of using unique_ptr in the
first place. Just leave it to the unique_ptr to deal with
deallocation, or adopt a different design.
JiiPee <no@notvalid.com>: Nov 24 01:19AM

On 24/11/2016 00:56, Chris Vine wrote:
> memory corruption
> and woe, because b->foo() would delete the A object, and b would try
> to do the same when it goes out of scope.
 
 
Thats what I also thought.
 
The reason I ask this is becouse with Microsoft MFC its quite common
practice for people to do:
 
delete this;
 
When the window-objects window gets destroyed:
 
void CMyDialog::OnNcDestroy()
{
CDialog::OnNcDestroy();
delete this;
}
 
So, is this a wrong approach? Many do this though....and I think also
MFC does that something inside the library?
 
(In this example we know that CMyDialog is created dynamically with new)
JiiPee <no@notvalid.com>: Nov 24 01:20AM

On 24/11/2016 00:56, Chris Vine wrote:
> you have it completely wrong. First you have not actually allocated
> an A object, so b->foo will dereference a null pointer and the program
> will terminate.
 
 
Yes, there was a mistake.. see my other post
JiiPee <no@notvalid.com>: Nov 24 01:26AM

On 24/11/2016 00:56, Chris Vine wrote:
> Just leave it to the unique_ptr to deal with
> deallocation, or adopt a different design.
 
 
So this means that "delete this;" is not a good practise, right? Because
it might lead to confusion.
Jerry Stuckle <jstucklex@attglobal.net>: Nov 23 10:57PM -0500

On 11/23/2016 8:19 PM, JiiPee wrote:
 
> So, is this a wrong approach? Many do this though....and I think also
> MFC does that something inside the library?
 
> (In this example we know that CMyDialog is created dynamically with new)
 
But MFC doesn't use unique_ptr, so someone has to delete it or you have
a memory leak. And after the return from OnNcDestroy() the object
should never be referenced again (and isn't in MFC).
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Nov 23 10:57PM -0500

On 11/23/2016 8:26 PM, JiiPee wrote:
>> deallocation, or adopt a different design.
 
> So this means that "delete this;" is not a good practise, right? Because
> it might lead to confusion.
 
It all depends on the circumstances. If you do use it, ensure to
document it.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 24 05:45AM +0100

On 24.11.2016 01:42, JiiPee wrote:
>> b.foo();
>> // (*) here: what is the state of b?
>> }
 
When `std::unique_ptr` destructor attempts to destroy the object it's
already destroyed, and you have Undefined Behavior.
 
The proper way for the object to self-destruct is to do that via the
single owner, here the smart pointer.
 
Which means the object needs knowledge of its owner, or be provided with
a self-destruct operation that does.
 
 
Cheers & hth.,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Nov 24 09:18AM +0200

On 24.11.2016 3:19, JiiPee wrote:
> {
> CDialog::OnNcDestroy();
> delete this;
 
After this, there must not be another delete called for this object.
This means that either the object was not managed by smart pointers at
all, or that OnNcDestroy() was called from the destructor of the last
smart pointer.
 
In case of MFC it is the former, the objects are managed by raw pointers
by using strict ownership conventions. This is possible because MFC is
single-threaded.
 
Cheers
Paavo
Paavo Helde <myfirstname@osa.pri.ee>: Nov 24 09:31AM +0200

On 24.11.2016 3:26, JiiPee wrote:
>> deallocation, or adopt a different design.
 
> So this means that "delete this;" is not a good practise, right? Because
> it might lead to confusion.
 
'Delete this;' is rarely a good practice. Since C++11 one has several
standardized smartpointers which should be used instead.
 
In general, a naked 'delete' should not appear in application level code
at all. If not for other reasons, then just because it is inherently
exception-unsafe.
 
With legacy frameworks like MFC one needs to use their conventions of
course, and if this requires writing 'delete this;' then so be it.
 
Cheers
Paavo
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 24 10:08AM

On Thu, 24 Nov 2016 01:26:26 +0000
> > deallocation, or adopt a different design.
 
> So this means that "delete this;" is not a good practise, right?
> Because it might lead to confusion.
 
'delete this' is OK in cases where an object is entirely self-owning.
Non-modal GUI dialogs in an asynchronous event loop are one of the few
examples - their lifetime is ended by the program user clicking on a
close button or the like (which are events which the object itself
receives and handles in many GUI systems), and bears no relation to
anything else in the program (apart from program termination). If the
dialog receives the click notification, it might as well kill itself
with 'delete this' rather than delegate that to some firing squad it
specially sets up for the purpose. You have to obey the usual
conventions - once 'delete this' has been called, no non-static member
data of the object may be accessed and no non-static methods of the
object may be called. The only thing the method can sensibly do is
return, which yours did.
 
I have code which does that with no embarassment. It's all a question
of clear ownership. If you use a unique_ptr to manage an object
allocated on free store, you are declaring that the unique_ptr (or some
other one to which it is moved) is responsible for managing lifetime.
In that case you should let the unique_ptr do its thing. For most
usages unique_ptr is ideal. If you need shared ownership then use
shared_ptr. Only in the case of self-ownership (usually, as I say, in
event driven programming) should you consider 'delete this'.
 
Chris
"Öö Tiib" <ootiib@hot.ee>: Nov 24 04:03AM -0800

On Thursday, 24 November 2016 09:31:45 UTC+2, Paavo Helde wrote:
 
> In general, a naked 'delete' should not appear in application level code
> at all. If not for other reasons, then just because it is inherently
> exception-unsafe.
 
Interesting fact that one usage of 'delete this' that I have seen was for
to achieve strong exception safety (erase-commit/rollback).
JiiPee <no@notvalid.com>: Nov 24 12:35PM

On 24/11/2016 03:57, Jerry Stuckle wrote:
> But MFC doesn't use unique_ptr, so someone has to delete it or you have
> a memory leak. And after the return from OnNcDestroy() the object
> should never be referenced again (and isn't in MFC).
 
 
but even if it is not a smart pointer, the user must still *know* that
the function will destroy it. Is there a risk here and confusion that if
the user forgots that its self deleted? How does the user remember that
in this occasion the object will be self-destroyed?
JiiPee <no@notvalid.com>: Nov 24 12:37PM

On 24/11/2016 07:31, Paavo Helde wrote:
> With legacy frameworks like MFC one needs to use their conventions of
> course, and if this requires writing 'delete this;' then so be it.
 
 
You would not mix the modern C++ with MFC?
JiiPee <no@notvalid.com>: Nov 24 12:42PM

Ok, this was pretty clear explanation. So in this occasion its ok
because MFC uses that convention.
 
On 24/11/2016 10:08, Chris Vine wrote:
"Christopher J. Pisz" <cpisz@austin.rr.com>: Nov 24 06:09AM -0600

I found this article:
http://www.drdobbs.com/the-standard-librarian-what-are-allocato/184403759
 
Although it predates C++11, I can't find anything more recent, so here I
am playing with the code and trying to understand it.
 
I get the following output from my code (listed below):
 
Allocated 16 bytes for a struct std::_Container_proxy
Complex Number constructed
Allocated 24 bytes for a class ComplexNumber
Complex Number copy constructed
Complex Number deconstructed
Complex Number deconstructed
Deallocated 24 bytes for a class ComplexNumber
Deallocated 16 bytes for a struct std::_Container_proxy
 
Why are 16 bytes allocated before space for the actual data I am putting
into the std::vector and what is a container_proxy?
 
When 'placement new' is called, is that when the object is being copy
constructed? and if I understand right, copy constructed into the memory
I allocated?
 
What is the second argument in pointer allocate(size_type n,
const_pointer = 0) ?
 
What is the second argument in void deallocate(pointer p, size_type) ?
 
This makes no sense to me. What is the max size supposed to be and why
is it a negative number? Or is this some unsigned/signed trickery?
 
size_type max_size() const
{
return static_cast<size_type>(-1) / sizeof(value_type);
}
 
 
Here is my listing:
 
// Standard Includes
#include <iostream>
 
//------------------------------------------------------------------------------
/// <summary>
/// A STL compliant custom allocator
/// After C++11 this changes a bit by dropping much boiler plate code
///
/// Based on Dr Dobbs article
///
http://www.drdobbs.com/the-standard-librarian-what-are-allocato/184403759
/// </summary>
template <class T>
class malloc_allocator
{
public:
typedef T value_type;
typedef value_type * pointer;
typedef const value_type * const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef std::size_t size_type;
// typedef std::ptrdiff_t difference_type; // Gives compile error
 
malloc_allocator()
{
// Allocators before C++11 are expected to be stateless
}
 
malloc_allocator(const malloc_allocator & rhs)
{
}
 
~malloc_allocator()
{
}
 
void operator =(const malloc_allocator & rhs) = delete;
 
bool operator == (const malloc_allocator<T> & rhs)
{
return true;
}
 
bool operator != (const malloc_allocator<T> & rhs)
{
return false;
}
 
template <class U>
malloc_allocator(const malloc_allocator<U> &)
{
}
 
template <class U>
struct rebind
{
typedef malloc_allocator<U> other;
};
 
pointer address(reference x) const
{
return &x;
}
 
const_pointer address(const_reference x) const
{
return &x;
}
 
pointer allocate(size_type n, const_pointer = 0)
{
const size_type numBytes = n * sizeof(T);
void * p = std::malloc(numBytes);
 
if (!p)
{
throw std::bad_alloc();
}
 
std::cout << "Allocated " << numBytes << " bytes for a " <<
typeid(T).name() << std::endl;
return static_cast<pointer>(p);
}
 
void deallocate(pointer p, size_type)
{
const size_type numBytes = sizeof(*p);
 
std::free(p);
std::cout << "Deallocated " << numBytes << " bytes for a " <<
typeid(T).name() << std::endl;
}
 
size_type max_size() const
{
return static_cast<size_type>(-1) / sizeof(value_type);
}
 
void construct(pointer p, const value_type & x)
{
// 'Placement new' constructs an object at a specified location
// The custom allocator seperates allocation from construction
new(p) value_type(x);
}
 
void destroy(pointer p)
{
p->~value_type();
}
};
 
// Template specialization for void type
// Our custom allocator does not work when a container refers to void
pointers.
// We refer to sizeof(T) and T& which is not legal when T is void.
// Therefore we must specialize.
// Leaves out everything except what is needed for referring to void
pointers
template<> class malloc_allocator<void>
{
typedef void value_type;
typedef void * pointer;
typedef const void * const_pointer;
 
template <class U>
struct rebind
{
typedef malloc_allocator<U> other;
};
};
 
//------------------------------------------------------------------------------
class ComplexNumber
{
public:
 
ComplexNumber(double realPart, double complexPart);
ComplexNumber(const ComplexNumber & rhs);
virtual ~ComplexNumber();
 
protected:
 
double m_realPart;
double m_complexPart;
};
 
//------------------------------------------------------------------------------
ComplexNumber::ComplexNumber(double realPart, double complexPart)
:
m_realPart(realPart)
, m_complexPart(complexPart)
{
std::cout << "Complex Number constructed" << std::endl;
}
 
//------------------------------------------------------------------------------
ComplexNumber::ComplexNumber(const ComplexNumber & rhs)
:
m_realPart(rhs.m_realPart)
, m_complexPart(rhs.m_complexPart)
{
std::cout << "Complex Number copy constructed" << std::endl;
}
 
//------------------------------------------------------------------------------
ComplexNumber::~ComplexNumber()
{
std::cout << "Complex Number deconstructed" << std::endl;
}
 
//------------------------------------------------------------------------------
void RunCustomAllocator()
{
std::vector<ComplexNumber, malloc_allocator<ComplexNumber> > myVector;
ComplexNumber number(1, 1);
myVector.push_back(number);
}
 
//------------------------------------------------------------------------------
int main(int argc, char * argv[])
{
// RunNoMemoryManagement();
// RunSimpleMemoryManagement();
 
RunCustomAllocator();
 
return 0;
}
mark <mark@invalid.invalid>: Nov 24 01:38PM +0100

On 2016-11-24 13:09, Christopher J. Pisz wrote:
> Deallocated 16 bytes for a struct std::_Container_proxy
 
> Why are 16 bytes allocated before space for the actual data I am putting
> into the std::vector and what is a container_proxy?
 
Probably iterator tracking / debugging:
<https://hadibrais.wordpress.com/2013/11/13/dissecting-the-c-stl-vector-part-2-constructors/>
 
> What is the second argument in pointer allocate(size_type n,
> const_pointer = 0) ?
 
> What is the second argument in void deallocate(pointer p, size_type) ?
 
http://en.cppreference.com/w/cpp/memory/allocator
 
> {
> return static_cast<size_type>(-1) / sizeof(value_type);
> }
 
For unsigned types, -1 is equivalent to numeric_limits<size_type>::max().
"Chris M. Thomasson" <invalid@invalid.invalid>: Nov 23 08:20PM -0800

On 11/23/2016 1:24 PM, Chris M. Thomasson wrote:
> ________________________________________
 
> This was back when I was still trying out custom allocation techniques
> in C++.
 
 
I am sad to say that MSVC 2015 has the exact same error for me! I get:
_________________________________________
custom_allocator::allocate(00BBD930, 2234)
custom_allocator::deallocate(00BBD930, 2234)
custom_allocator::allocate(00BC0038, 11170)
custom_allocator::deallocate(00BC0038, 2234)
_________________________________________
 
This is very wrong!
 
However, it works online here in a different compiler:
 
http://cpp.sh/94sf7
_________________________________________
custom_allocator::allocate(0x20b0900, 2234)
custom_allocator::deallocate(0x20b0900, 2234)
custom_allocator::allocate(0x20b0900, 11178)
custom_allocator::deallocate(0x20b0900, 11178)
_________________________________________
 
and on GCC.
 
AFAICT, MSVC has a bug here in Version 14.0.25424.00 Update 3 at least...
 
Damn.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 24 10:50AM

On Wed, 23 Nov 2016 20:20:00 -0800
> AFAICT, MSVC has a bug here in Version 14.0.25424.00 Update 3 at
> least...
 
> Damn.
 
This is a really old bug in delete[] which has been around for ages,
and which Microsoft will readily admit to. However they say they can't
change it because it would break code which relies on the faulty
implementation (not least their own Windows operating system). It has
cropped up on this newsgroup a few times before. What the size_t
argument is passed in operator delete[] is the element size for the type
for which new[] was called, and not the allocated block size. Quite
what led them to think that is what the standard requires is beyond me.
 
The first suggested work-around is to have your class specific operator
new[] and operator delete[] forward to global operator new[] and
global operator delete[] so that your custom allocator only works when
allocating individual objects (or to not provide class specific operator
new[] and operator delete[] at all, which has the same effect), which is
what most people do. If you really need custom allocation for arrays
and the object is not std::allocator aware, the other workaround is to
use the initial few bytes of any memory allocated with new[] (say, an
unsigned int's worth) to the size of the allocation, and to return not
the beginning of the memory block allocated, but the address immediately
after the int (the start of "object space"). operator delete[] can then
read back four bytes and obtain the int value when it comes to delete[]
time.
mark <mark@invalid.invalid>: Nov 24 12:50PM +0100

On 2016-11-24 11:50, Chris Vine wrote:
> after the int (the start of "object space"). operator delete[] can then
> read back four bytes and obtain the int value when it comes to delete[]
> time.
 
How do you read back those 4 bytes without relying on undefined behavior?
 
There are compilers (including GCC) that may mis-compile code like that
(it's C, but the restrictions on C++ pointer math should be similar enough):
"C memory object and value semantics: the space of de facto and ISO
standards"
https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf
Lino <lino@net.com>: Nov 24 12:37AM +0100

Louis Krupp wrote:
 
> Does it work? If so, congratulations! If not, please post your code
> and your results.
 
> Louis
 
 
------------------------------------------------
code written in AFL language (Amibroker Formula Language)
[https://www.amibroker.com/guide/AFL.html]
 
 
AB = CreateObject("Broker.Application");
sts = AB.Stocks();
Qty = sts.Count;
 
for( i = Qty - 1; i >= 0; i = i - 1 )
{
st = sts.Item( i );
Ticker = st.Ticker;
printf("changing " + Ticker + "\n" );
Length = StrLen(Ticker );
if( StrFind(Ticker, "TO:") )
 
st.Ticker= "TC-"+StrRight(Ticker,Lenght+3);
 
}
-------------------------------------------------------------
 
 
 
haven't a code result.
The result is in the symbol changed on my database on the screen.
 
...and the results are 2 errors:
 
 
[1]. change only 1 symbol a time (every time i click "apply") and I think
it's a "FOR Cycle" problem.
 
 
 
[2]. Example: I have a list symbols on the left side [below] -----> and the
result in the symbols modified [every time I click apply script] in the
right side.
 
 
TO:A TC-T:A [wrong]
TO:DE TC-:DE [wrong]
TO:ASD TC-ASD OK <<<<<<< Thats OK (I want this)
TO:AXMA TC-XMA [Wrong]
TO:ERJTT TC-JTT [wrong]
 
 
I want to change in this case "ONLY" the "TO:" [or in other case the part of
string that I want to change from the first chacacter on the left] leaving
the rest the same as originally printed.
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Nov 23 07:44PM -0700

> Length = StrLen(Ticker );
> if( StrFind(Ticker, "TO:") )
 
> st.Ticker= "TC-"+StrRight(Ticker,Lenght+3);
 
What is 'Lenght', and why are you adding 3 to it?
 
Does AFL allow you to use variables you haven't declared?
 
Louis
Lino <lino@net.com>: Nov 24 09:43AM +0100

Louis Krupp ha usato la sua tastiera per scrivere :
 
> What is 'Lenght', and why are you adding 3 to it?
 
> Does AFL allow you to use variables you haven't declared?
 
> Louis
 
 
 
please note that I'm not a programmer.
I have only copy an existant code to adapt it for this little work for
changing the name ot multiple symbol on Dbase.
 
-I think (but not sure) the plus (on Lenght) isin't necessary on StrRight
[https://www.amibroker.com/guide/afl/strright.html]
 
 
-Lenght is a lenght (number) of the sting of the symbol (StrLeng)
http://www.amibroker.com/guide/afl/strlen.html
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: