Sunday, February 2, 2014

comp.lang.c++ - 26 new messages in 8 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* What is the disadvantage with C++ in Embedded systems? - 4 messages, 3
authors
http://groups.google.com/group/comp.lang.c++/t/d2c6dd66860beb15?hl=en
* goto label inside of if statement - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/7c222b0d5330287c?hl=en
* illegal void argument - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/c039b912fa7c33f7?hl=en
* Boost - 4 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/81738d66827a11c8?hl=en
* Placement new[] - 5 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/2f55035da7d1c7be?hl=en
* i really need help - 5 messages, 5 authors
http://groups.google.com/group/comp.lang.c++/t/002712afc07dfe81?hl=en
* How does the name lookup work in this case? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/f7e465d3b9e6c21f?hl=en
* Hey, talk.origins crank: - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/f20d73dd3f975d02?hl=en

==============================================================================
TOPIC: What is the disadvantage with C++ in Embedded systems?
http://groups.google.com/group/comp.lang.c++/t/d2c6dd66860beb15?hl=en
==============================================================================

== 1 of 4 ==
Date: Wed, Jan 29 2014 8:52 am
From: "Alf P. Steinbach"


On 29.01.2014 17:31, Robert Wessel wrote:
> On Wed, 29 Jan 2014 15:01:04 +0100, "Alf P. Steinbach"
> <alf.p.steinbach+usenet@gmail.com> wrote:
>
>> On 25.01.2014 17:48, deepadivakaruni@gmail.com wrote:
>>> i think so c++ is more complicated when compared to c.
>>
>> Yes, but that is not a disadvantage of the language for embedded systems.
>>
>>
>>> And also the many keywords are used to perform only one application.
>>
>> Well, ditto.
>>
>> * * *
>>
>> Thread subject line:
>> "What is the disadvantage with C++ in Embedded systems?"
>>
>> Please state your question in the article, not only in the subject line.
>>
>> From the statements in the article one would think you were asking
>> something unspecified about the language complexity.
>>
>> * * *
>>
>> A main disadvantage of C++ for embedded systems, and for OS drivers
>> etc., compared to C, is that full C++ requires much RUNTIME SUPPORT that
>> C doesn't require, in particular for dynamic initialization of statics,
>> exception handling and RTTI like dynamic_cast.
>
>
> Well, it requires *some* runtime support for those things. "Much" is
> arguable.
>
> For example, RTTI usually requires only a pointer in each vtable (per
> vtable, so per class, not per instance) to a (short) block of type
> information (typical overhead is under 50 bytes per class). The
> routines needed to deal with that are pretty short too (depending on
> the use, typeid can be very short - a lookup in the vtable, and
> dynamic_cast requires a bit of a walk of the class hierarchy graph).
> Other than the per-class memory overhead, RTTI doesn't impose any
> execution time costs, unless you actually do a typeid or dynamic_cast.

I wasn't talking about size or time costs, but rather, the need for that
information to exist and be initialized.


> Exceptions usually require a few extra instructions at routine/block
> entry and exit, a few bytes of stack space for each of those, and a
> small amount of code at the throw and catch (some (small) common
> chunks of which sometimes end up the library).

Exceptions require far more than you list (e.g. to support
std::exception_ptr), but ditto: it's not the space or time overhead
that's at issue.



> Dynamic initialization of statics (and ctors on statics), require the
> compilation of a list of pointers to each such static, and then
> runtime support to step through that list, calling each ctor in turn
> (IOW, several lines of code), and, of course the actual code for the
> initialization of each object.

Ditto: while space and time may be relevant on some devices, they're not
showstoppers, but the assumption of control that's inherent in C++'s
requirements of runtime support, can be.

At one time the issues that I pointed at meant that these features were
simply not available for some environments, As I recall, in particular
one mobile phone OS didn't support dynamic initialization of statics,
exceptions or RTTI. One had to make do with a slightly lobotomized
ARM-style C++.

Things have changed and are changing, especially for CUDA programming
(which I need to delve into!), but the issues are there still.


Cheers & hth.,

- Alf





== 2 of 4 ==
Date: Wed, Jan 29 2014 10:11 am
From: Wouter van Ooijen


Robert Wessel schreef op 29-Jan-14 5:31 PM:
> Exceptions usually require a few extra instructions at routine/block
> entry and exit, a few bytes of stack space for each of those, and a
> small amount of code at the throw and catch (some (small) common
> chunks of which sometimes end up the library).
>
> So those have some overhead, but it's not like they're going to drag
> in hundreds of KB of runtime library or triple the size of the object
> code, and what embedded compiler doesn't have at least something in
> the CRT anyway?

More a library implementation issue than a language issue, but when I
build my Cortex M0 application with exception handling some exception
handler (the one around main?) is linked along and the minimum
application size is ~ 500 Kb. And my poor chip has only 8Kb.

Wouter





== 3 of 4 ==
Date: Wed, Jan 29 2014 10:41 am
From: Jorgen Grahn


On Wed, 2014-01-29, Wouter van Ooijen wrote:
> Robert Wessel schreef op 29-Jan-14 5:31 PM:
>> Exceptions usually require a few extra instructions at routine/block
>> entry and exit, a few bytes of stack space for each of those, and a
>> small amount of code at the throw and catch (some (small) common
>> chunks of which sometimes end up the library).
>>
>> So those have some overhead, but it's not like they're going to drag
>> in hundreds of KB of runtime library or triple the size of the object
>> code, and what embedded compiler doesn't have at least something in
>> the CRT anyway?
>
> More a library implementation issue than a language issue, but when I
> build my Cortex M0 application with exception handling some exception
> handler (the one around main?) is linked along and the minimum
> application size is ~ 500 Kb. And my poor chip has only 8Kb.

/Definitely/ not a language issue! Half a megabyte is absurdly much.
Pulling in iostreams /and/ stdio might /possibly/ explain it.
What does the symbol table say?

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .




== 4 of 4 ==
Date: Wed, Jan 29 2014 11:12 am
From: Wouter van Ooijen


Jorgen Grahn schreef op 29-Jan-14 7:41 PM:
> /Definitely/ not a language issue! Half a megabyte is absurdly much.
> Pulling in iostreams /and/ stdio might /possibly/ explain it.
> What does the symbol table say?

iostreams indeed.

Wouter






==============================================================================
TOPIC: goto label inside of if statement
http://groups.google.com/group/comp.lang.c++/t/7c222b0d5330287c?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Jan 29 2014 1:29 pm
From: Vir Campestris


On 28/01/2014 22:11, Jax wrote:
> Andy.... you make me pause for thought. If I understand the implication of
> what you wrote, then it means I haven't learned my first*real* C++
> command!

Make note of Victor's post earlier in the thread. He's much better at
C++ than I am.

Andy




== 2 of 2 ==
Date: Thurs, Jan 30 2014 9:12 am
From: Jax


Vir Campestris <vir.campestris@invalid.invalid> wrote in
news:oJSdnc0M0ewv73TPnZ2dnUVZ8gCdnZ2d@brightview.co.uk:

> On 28/01/2014 22:11, Jax wrote:
>> Andy.... you make me pause for thought. If I understand the implication of
>> what you wrote, then it means I haven't learned my first*real* C++
>> command!
>
> Make note of Victor's post earlier in the thread. He's much better at
> C++ than I am.
>
> Andy

Wilco!

--
Jax :)





==============================================================================
TOPIC: illegal void argument
http://groups.google.com/group/comp.lang.c++/t/c039b912fa7c33f7?hl=en
==============================================================================

== 1 of 4 ==
Date: Wed, Jan 29 2014 2:01 pm
From: Marcel Müller


On 29.01.14 16.29, Victor Bazarov wrote:
> Inconsistency? Returning from a 'void' function by calling another void
> function is syntactic sugar.

I do not agree with you. In template programming it is essential to
accept this syntax, e.g. for function adapters.

> How would you reconcile passing a void
> argument with overloading? What about conversions?

This point is a different story. First, it have to be defined what
should happen when void is passed in the parameter list. This has not
yet been defined.


> And the clincher for me is the question "what problem does it solve?"
> The ability to return an expression from a void function was added to
> help resolve some template generation problems.

Exactly. And maybe in conjunction with variadic templates at some time
passing void to a function may become well defined.

> And in this case it
> seems that the sole purpose is obfuscation...

?

Marcel




== 2 of 4 ==
Date: Wed, Jan 29 2014 2:22 pm
From: Victor Bazarov


On 1/29/2014 5:01 PM, Marcel Müller wrote:
> On 29.01.14 16.29, Victor Bazarov wrote:
>>[..]
>> And in this case it
>> seems that the sole purpose is obfuscation...
>
> ?

Just my reference to the OP's comment, "Fun way to confuse novices".

V
--
I do not respond to top-posted replies, please don't ask




== 3 of 4 ==
Date: Thurs, Jan 30 2014 6:30 am
From: Öö Tiib


On Wednesday, 29 January 2014 17:29:25 UTC+2, Victor Bazarov wrote:
> On 1/29/2014 10:04 AM, Öö Tiib wrote:
> > In C++ we can have void return type and we can "return" it:
> >
> > void foo();
> >
> > void bar()
> > {
> > return (void)42; // ok #1
> > return foo(); // ok #2
> > }
> >
> > Fun way to confuse novices indeed. However, it appears that we can not (for
> > whatever unknown reason) pass void arguments:
> >
> > void bad()
> > {
> > foo((void)42); // illegal
> > }
> >
> > Even if I think I will be extra clever and add overload of 'foo' that supposedly
> > accepts anything ...
> >
> > void foo(...);
> >
> > ... then I get different failures or successes on different mac/ubuntu clang/gcc
> > versions. Seems that compilers are confused.
> >
> > Is there reason why we have such inconsistency?
>
> Inconsistency? Returning from a 'void' function by calling another void
> function is syntactic sugar. How would you reconcile passing a void
> argument with overloading?
>
> What about conversions? I am too lazy to
> check (with a compiler or the Standard), maybe you know, what would
> happen if you do
>
> int someth();
>
> void foo() {
> return someth();
> }
>
> ? Would it be OK? IOW, is it the same as
>
> void foo() {
> someth();
> return;
> }

Yes, if to use explicit void cast in return then it would work like that.
The compiler may not implicitly cast to void.

> ? If it's OK, then any expression value *can* be converted to 'void'
> when used in a 'return' from a 'void' function. Would you allow the
> same for any expression converted as a single argument? Or does it have
> to be explicit?

Yes it has to be explicit. The void cast is perhaps illusionary.

> And the clincher for me is the question "what problem does it solve?"
> The ability to return an expression from a void function was added to
> help resolve some template generation problems. And in this case it
> seems that the sole purpose is obfuscation...

My comment about "fun way to confuse novices" was may be too
harsh but that is how it feels because there is *illusionary* usage of
"values" of void type but such usage is only available for rather
*narrow* set of cases (like that 'return' statement).

Why ability to return is more essential for template programming than
ability to "pass" it to other callable? Other problem is that passing void
arguments does not seem to be even forbidden ... it seems to be
undefined.





== 4 of 4 ==
Date: Thurs, Jan 30 2014 6:51 am
From: Victor Bazarov


On 1/30/2014 9:30 AM, Öö Tiib wrote:
>[..]
> Why ability to return is more essential for template programming than
> ability to "pass" it to other callable? Other problem is that passing void
> arguments does not seem to be even forbidden ... it seems to be
> undefined.

A function wrapper needs the return value type defined (or deduced) and
if/when the call is forwarded to the wrapped object, the return value
needs to be retained and returned to the caller [of the wrapper]. I am
guessing (since I've not followed that particular development in the
language) it to be the reason for introducing the ability to have a void
expression in a return statement. If I were to invent a situation in
which "passing" would be generically necessary, I can only think (right
now) of a "broker" emulator, some mechanism that calls one side and then
the other, while passing the return value of one to the other as its
argument, without necessarily knowing (or caring) what that value is or
where it exists (in the case of 'void'). Apparently the library
designers didn't think it common enough a problem to introduce such a
mechanism into the library. IOW, if you need one, you'd roll your own
instead of instantiating some standard template...

V
--
I do not respond to top-posted replies, please don't ask





==============================================================================
TOPIC: Boost
http://groups.google.com/group/comp.lang.c++/t/81738d66827a11c8?hl=en
==============================================================================

== 1 of 4 ==
Date: Wed, Jan 29 2014 3:03 pm
From: woodbrian77@gmail.com


On Sunday, January 26, 2014 4:56:28 PM UTC-6, Ian Collins wrote:
> woodbrian77@gmail.com wrote:
>
> > If you had said --
> >
> > it sometimes has to inter-operate
> >
>
> > I'd agree. I know of a few companies that write C++
> > programs that communicate with each other. That's
> > not exactly unheard of.
>
> Probably the most common type of "service" these days is the web
> service. Web services almost exclusively use SOAP. If you are going to
> write the back ends for web pages in C++, you will probably have to use
> JSON to communicate with the client JavaScript.


I've been reading about JSON some. The following is
maybe due to some misunderstanding, but it seems
JSON can only deal with user defined objects.

I have a message template (not a C++ template) that
looks like this:

@out (::cmw::marshalling_integer, const char*)

(A function is generated based on that.)

IIuc, with JSON, I'd have to create a class that has
those two types in it and then marshal an instance of
that type. I like not having to do that as there's
no need currently for such a class. Those two pieces
of data are from the command line and I just forward
them to the marshalling function without having to
create an object that's only use would be marshalling
it's data members. I will admit it wouldn't take long
to construct such an object, but there's a wrinkle.
If the class were:

class front_tier_type
{
cmw::marshalling_integer account_number;
char* path;
};

That class won't work for me in my middle tier where
it doesn't hurt to store the data from the path variable
in a std::string. I have to store it somewhere in the
middle tier so I choose to put it in a std::string.

Constructing a front_tier_type would be fast, but if
I changed it to have a std:string instead of a char*
it gets more expensive. I don't want to have to pay
for that in the front tier. So iiuc, JSON based
approach would have one class on sending side and
another on the receiving side. The other approach I
described is also different on the sending and receiving
ends, but is more efficient.

If there were more than two pieces of data, constructing
an object becomes more of a waste.

The C++ route seems to offer more flexibility than
the JSON approach.


>
>
> > And as I said I'm open to working on adding support
> > for another language, but I don't think that language
> > will be Java. Python or C# is more likely.
> >
>
> > I think scientific apps and games often use binary serialization.
> >

> By using a proprietary binary format,

The format isn't a secret.

> you are restricting yourself to a
> narrow range of applications. The easiest way to support other
> languages is to use a well known on wire format.

I may go back to this angle.

Brian
Ebenezer Enterprises
http://webEbenezer.net




== 2 of 4 ==
Date: Wed, Jan 29 2014 4:32 pm
From: Ian Collins


woodbrian77@gmail.com wrote:
> On Sunday, January 26, 2014 4:56:28 PM UTC-6, Ian Collins wrote:
>> woodbrian77@gmail.com wrote:
>>
>>> If you had said --
>>>
>>> it sometimes has to inter-operate
>>>
>>> I'd agree. I know of a few companies that write C++
>>> programs that communicate with each other. That's
>>> not exactly unheard of.
>>
>> Probably the most common type of "service" these days is the web
>> service. Web services almost exclusively use SOAP. If you are going to
>> write the back ends for web pages in C++, you will probably have to use
>> JSON to communicate with the client JavaScript.
>
> I've been reading about JSON some. The following is
> maybe due to some misunderstanding, but it seems
> JSON can only deal with user defined objects.

It depends on how you use JSON and your chosen library. I would write
something like:

json::Object blob;
blob["number"] = accountNumber;
blob["name"] = accountName;

std::cout << blob;

<snip>

> Constructing a front_tier_type would be fast, but if
> I changed it to have a std:string instead of a char*
> it gets more expensive. I don't want to have to pay
> for that in the front tier. So iiuc, JSON based
> approach would have one class on sending side and
> another on the receiving side. The other approach I
> described is also different on the sending and receiving
> ends, but is more efficient.
>
> If there were more than two pieces of data, constructing
> an object becomes more of a waste.
>
> The C++ route seems to offer more flexibility than
> the JSON approach.

In cases where speed of serialisation isn't critical (most cases I'd
suggest), the flexibility and interoperability of text on the wire wins out.

I often use all or part of the received JSON object directly in the
sever code, so it never gets converted to something else. I guess this
habit comes form having written a lot of JavaScript.

>>> And as I said I'm open to working on adding support
>>> for another language, but I don't think that language
>>> will be Java. Python or C# is more likely.
>>>
>>
>>> I think scientific apps and games often use binary serialization.
>
>> By using a proprietary binary format,
>
> The format isn't a secret.

But you's have to convince others to adopt it.

--
Ian Collins




== 3 of 4 ==
Date: Wed, Jan 29 2014 7:36 pm
From: woodbrian77@gmail.com


On Wednesday, January 29, 2014 6:32:30 PM UTC-6, Ian Collins wrote:
> woodbrian77@gmail.com wrote:
>
> > On Sunday, January 26, 2014 4:56:28 PM UTC-6, Ian Collins wrote:
>
> >> Probably the most common type of "service" these days is the web
>
> >> service. Web services almost exclusively use SOAP. If you are going to
>
> >> write the back ends for web pages in C++, you will probably have to use
>
> >> JSON to communicate with the client JavaScript.
>
> >
>
> > I've been reading about JSON some. The following is
> > maybe due to some misunderstanding, but it seems
> > JSON can only deal with user defined objects.
>
> It depends on how you use JSON and your chosen library. I would write
> something like:
>
> json::Object blob;
> blob["number"] = accountNumber;
> blob["name"] = accountName;
>
> std::cout << blob;
>

That kind of helps, but the indices ("number" and "name")
are a problem. I don't have a means of getting that
information from a user like I do if they provide a header
file with data member names.

Let me change the messsage template a little

@out (int, const char*)

The generated function for that will have a1 and a2
for the names of the arguments. So

json::Object blob;
blob["a1"] = a1;
blob["a2"] = a2;

That doesn't work for me on the receiving side where
I have a user defined type.

>
>
> > The C++ route seems to offer more flexibility than
> > the JSON approach.
>
> In cases where speed of serialisation isn't critical (most cases I'd
> suggest), the flexibility and interoperability of text on the wire wins out.
>

Well where speed is critical, there's a good chance they'll
be using C++ so that much is promising from my perspective.

> I often use all or part of the received JSON object directly in the
> sever code, so it never gets converted to something else. I guess this
> habit comes form having written a lot of JavaScript.
>

I recall your saying something like that previously. I'd like
to know how accessing a JSON object compares to accessing a C++
object. Is it a lot slower? I recall Juha talking about
something that may have been similar with Objective C.


Brian
Ebenezer Enterprises
http://webEbenezer.net




== 4 of 4 ==
Date: Wed, Jan 29 2014 10:45 pm
From: Ian Collins


woodbrian77@gmail.com wrote:
> On Wednesday, January 29, 2014 6:32:30 PM UTC-6, Ian Collins wrote:
>
>> I often use all or part of the received JSON object directly in the
>> sever code, so it never gets converted to something else. I guess this
>> habit comes form having written a lot of JavaScript.
>>
>
> I recall your saying something like that previously. I'd like
> to know how accessing a JSON object compares to accessing a C++
> object. Is it a lot slower? I recall Juha talking about
> something that may have been similar with Objective C.

Given a JSON object is a C++ object, the access will depend on the
complexity of the object. My library is designed for programmer
convenience first, efficiency a close second. I wanted to support
arbitrary nesting, such as

json::Object blob;

blob["one"]["two"]["three"]["four"] << 1 << 2 << "hello";

which creates this object:

{"one":{"two":{"three":{"four":[1,2,"hello"]}}}}

This requires a degree of indirection than a more basic implementation
would.

If I want to use an internal C++ object, I code generate (usually from
an Open Office document) to/from JSON methods for the object's data.

--
Ian Collins





==============================================================================
TOPIC: Placement new[]
http://groups.google.com/group/comp.lang.c++/t/2f55035da7d1c7be?hl=en
==============================================================================

== 1 of 5 ==
Date: Thurs, Jan 30 2014 12:18 am
From: Joe The Smoe


Hi,

to manage memory allocation for a multi-threaded application and reduce
the use of mutex, each thread is given an object of a class named "pool"
which allocates, recycles and eventually releases a set of memory
blocks (the classical memory pool).

The different objects allocated by each thread can now be allocated
using the given pool object thanks to a placement new and new[]
operators given to each concerned class.

The problem I meet is that I have something working pretty well except
for the placement new[] which places the first element of the array 4
bytes after the address returned by the new[] operator. This causes me
some problem at the time the array has to be released because the memory
address of the array (the address of the first element) does not match
the address given by the pool to the placement new[] operator (for the
pool this is not a memory block that it has allocated).

OK, I could shift the array address by four bytes and it would work but,
I'd rather like to understand.

Thanks for any enlightenment! :)

Cheers,
Joe.

P.S: the placement new, new[], delete, and delete[] operators are
textually identical for each class, I can use a #define macro to add
them to each class. But, is there a better C++ way of doing that?




== 2 of 5 ==
Date: Thurs, Jan 30 2014 12:38 am
From: Wouter van Ooijen


Joe The Smoe schreef op 30-Jan-14 9:18 AM:
> The problem I meet is that I have something working pretty well except
> for the placement new[] which places the first element of the array 4
> bytes after the address returned by the new[] operator.

Ordinary new and delete deal with a pointer to a fixed type, hence known
size of the object (the compiler can supply the size to the delete call).

Not so for the delete[] operator: it gets a pointer to the first entry,
but there can be just that one entry, but it could equally be a
1000-entry array. There is no guaranteed way for the compiler to known
this at the delete. Hence a common implementation of new[] puts the size
in front of the allocated block of memory, so delete[] can find it and
knows the size of the block.

> P.S: the placement new, new[], delete, and delete[] operators are
> textually identical for each class, I can use a #define macro to add
> them to each class. But, is there a better C++ way of doing that?

Inherit from a base class?

Wouter





== 3 of 5 ==
Date: Thurs, Jan 30 2014 1:13 am
From: Thomas Richter


Am 30.01.2014 09:18, schrieb Joe The Smoe:

> to manage memory allocation for a multi-threaded application and reduce
> the use of mutex, each thread is given an object of a class named "pool"
> which allocates, recycles and eventually releases a set of memory
> blocks (the classical memory pool).
>
> The different objects allocated by each thread can now be allocated
> using the given pool object thanks to a placement new and new[]
> operators given to each concerned class.
>
> The problem I meet is that I have something working pretty well except
> for the placement new[] which places the first element of the array 4
> bytes after the address returned by the new[] operator.

This is a quite typical strategy, namely to be able to record the number
of elements the corresponding delete[] must destroy.


> This causes me
> some problem at the time the array has to be released because the memory
> address of the array (the address of the first element) does not match
> the address given by the pool to the placement new[] operator (for the
> pool this is not a memory block that it has allocated).

How, actually, are you releasing the memory? If you delete the objects
by delete[], as you should (and not delete, without the brackets), you
should get the right memory address, adjusted with the offset. If this
is not the case, it is possibly a compiler bug (g++ does *not* show this
bug).

Note well you need to provide four operator deletes:

operator delete(void *);
deletes objects. You need to find your pool from the object. This delete
is used for regular delete in the program flow, even if deleting objects
from the pool.

operator delete[](void *);
Used for regular array destruction.

operator delete(void *,Pool);
used if an operator-new fails in the construction of an object in the
initializer list

operator delete[](void *,Pool);
the same for arrays.

Note specifically that your regular delete operator does *not* get the
pool passed in, even if it needs it. It's up to your new()
implementation to store it in an appropriate place if required. Plus,
"placement new" does not match "placement delete" as one may think.
"placement new" is complemented by "regular delete" plus "placement delete".

Greetings,
Thomas




== 4 of 5 ==
Date: Thurs, Jan 30 2014 5:03 am
From: Joe The Smoe


Le 30/01/2014 09:38, Wouter van Ooijen a écrit :
> Joe The Smoe schreef op 30-Jan-14 9:18 AM:
>> The problem I meet is that I have something working pretty well except
>> for the placement new[] which places the first element of the array 4
>> bytes after the address returned by the new[] operator.
>
> Ordinary new and delete deal with a pointer to a fixed type, hence known
> size of the object (the compiler can supply the size to the delete call).
>
> Not so for the delete[] operator: it gets a pointer to the first entry,
> but there can be just that one entry, but it could equally be a
> 1000-entry array. There is no guaranteed way for the compiler to known
> this at the delete. Hence a common implementation of new[] puts the size
> in front of the allocated block of memory, so delete[] can find it and
> knows the size of the block.

OK, I understand.

So, my implementation of the class pool is probably wrong. I intended to
put a pointer to the allocating pool object just before the allocated
block asked by a placement new/new[] in order to allow only code
modification by replacing the new operator by a it placement's
counterpart, keeping the delete invocation equal:

// adding a thread local pool object
pool p();

// using placement new in place of usual new operator
toto *ptr = new (p) toto(3);

... (doing something with ptr)

// but object get deleted normally (which that's the point is
// not the common way of doing, I admit...)
delete ptr;

where the delete operator for the class toto is taken from its parent
class "on_pool" --- thanks for the hint :) :

class on_pool
{
public:
// get_pool() returns the address of the allocating pool
// for "this" by fetching the field placed before
// the object's address: "this - sizeof(pool *)" bytes
pool & get_pool() const
{ return **((pool **)(pool::shift_left((void *)this))); };

// as expected the placement new operator
void *operator new(size_t n_byte, pool & p)
{ return p.alloc(n_byte); };

// and its associated "on-exception" delete operator
void operator delete(void *ptr, pool & p)
{ p.dealloc(ptr); };

// the delete operator overwritten to release address
// for the associated pool
void operator delete(void *ptr)
{ ((on_pool *)ptr)->get_pool().dealloc(ptr); };

// this works fine, but doing the same for placement new[]
// and the on_pool::delete[] operators fails because
// delete[] should not be used against object allocated
// by a placement new[] ... I'm hitting compiler internal's
// implementation of new[] and delete[] default operators.
};


class toto: public on_pool
{
...
};


Sight ... :-(

I wished I could abstract well the use of placement new in the current
code, but it seems I cannot avoid directly calling the destructor and
then the delete[] operator. Which to my humble point of view brings a
big difference about the readability of the code and which is source of
error (delete without prior desctructor call, and viceversa),

All the block recycling is done by the pool class not
by the caller (allocation/release abstraction) but I cannot abstract for
the caller the fact that the memory is allocated on the pool by just the
slightly modifying the "new" invocation...

*Sight*


>
>> P.S: the placement new, new[], delete, and delete[] operators are
>> textually identical for each class, I can use a #define macro to add
>> them to each class. But, is there a better C++ way of doing that?
>
> Inherit from a base class?

Yes, I stupidly thought the new and delete operator where not
inheritable... Just tested it and it perfectly works! Thanks. :)





== 5 of 5 ==
Date: Thurs, Jan 30 2014 8:38 am
From: Thomas Richter


Am 30.01.2014 14:03, schrieb Joe The Smoe:

> OK, I understand.
>
> So, my implementation of the class pool is probably wrong. I intended to
> put a pointer to the allocating pool object just before the allocated
> block asked by a placement new/new[] in order to allow only code
> modification by replacing the new operator by a it placement's
> counterpart, keeping the delete invocation equal:

...

Couple of problems with this code, namely the alignment might not be
right. But if operator new[] and operator delete[] are implemented in
the same way, then *that* part should be correct. I'm a bit too lazy to
try your code with g++, but I'll just share mine if you want to take it.

Here's an implementation that works with g++: What I show here is the
class you need to inherit from to be able to "pool allocate" any
derived classes.

class JObject {
private:
// Make Operator New without arguments private here.
// They must not be used.
void *operator new[](size_t)
{
assert(false);
return (void *)1; // GNU doesn't accept NULL here. This should
throw as well.
}
void *operator new(size_t)
{
assert(false);
return (void *)1;
}
//
// Private structure for effective arena-new management:
//
// Due to bugs in both the GCC and the VS, we must keep the
// size in the memory holder as well. The size parameter of
// the delete operator is just broken (a little broken on GCC,
// a lot broken on VS).
// This is still slightly more effective than using AllocVec
// here.
// *BIG SIGH*
union MemoryHolder {
// This union here enforces alignment
// of the data.
struct {
// back-pointer to the environment
class Environ *mh_pEnviron;
size_t mh_ulSize;
} mh;
// The following are here strictly for alignment
// reasons.
union Environ::Align mh_Align;
};
//
public:
// An overloaded "new" operator to allocate memory from the
// environment.
static void *operator new[](size_t size,class Environ *env)
{
union MemoryHolder *mem;
// Keep the memory holder here as well
size += sizeof(union MemoryHolder);
// Now allocate the memory from the environment.
mem = (union MemoryHolder *)env->AllocMem(size);
// Install the environment pointer and (possibly) the size
mem->mh.mh_pEnviron = env;
mem->mh.mh_ulSize = size;
return (void *)(mem + 1);
}
//
static void *operator new(size_t size,class Environ *env)
{
union MemoryHolder *mem;
// Keep the memory holder here as well
size += sizeof(union MemoryHolder);
// Now allocate the memory from the environment.
mem = (union MemoryHolder *)env->AllocMem(size);
// Install the environment pointer and (possibly) the size
mem->mh.mh_pEnviron = env;
mem->mh.mh_ulSize = size;
return (void *)(mem + 1);
}
//
//
// An overloaded "delete" operator to remove memory from the
// environment.
static void operator delete[](void *obj)
{
if (obj) {
union MemoryHolder *mem = ((union MemoryHolder *)(obj)) - 1;
mem->mh.mh_pEnviron->FreeMem(mem,mem->mh.mh_ulSize);
}
}
//
//
static void operator delete(void *obj)
{
if (obj) {
union MemoryHolder *mem = ((union MemoryHolder *)(obj)) - 1;
mem->mh.mh_pEnviron->FreeMem(mem,mem->mh.mh_ulSize);
}
}
};

The "Environment" is what your pool is. It provides functions AllocMem()
and FreeMem() that handle memory. Both require a pointer and a size. It
also contains a small union of the following type:

union Align {
UBYTE a_byte;
UWORD a_word;
ULONG a_int;
FLOAT a_float;
DOUBLE a_double;
UQUAD a_quad;
APTR a_ptr;
};

that is just there to ensure correct alignment of all types. The UPPER
CASE names there are environment specific types and set accordingly,
using autoconf.

The construction works fine with g++, and VS, though a couple of bugs
were present that required me to keep the size in the allocation itself
because the compiler provided value was, for some versions of the
compilers, incorrect.

To use it, first derive from JObject:

class bla : public JObject {
...
}

and then:

foo = new(environ) bla(...);

delete foo;

does what it should do, including arrays (tested). If it does not,
you're mixing new[] with delete, or new with delete[].

HTHH,
Thomas






==============================================================================
TOPIC: i really need help
http://groups.google.com/group/comp.lang.c++/t/002712afc07dfe81?hl=en
==============================================================================

== 1 of 5 ==
Date: Thurs, Jan 30 2014 7:34 am
From: mary8shtr@gmail.com


Hi.I joined recently to this group .I want write a program in c++ language.one program in c++ that receive two char array from user and print all of state built by this tow arryas.for example users enter "abc" and "mn".program should show abcmn , abmnc , amnbc , mnabc ,mabcn ,manbc, mabnc , ambnc ,ambcn ,abmcn as output.pleas answer me.I very thought on this solution.but I couldn't solve it.and i need it early.I thanks very much if anyone answer me faster.




== 2 of 5 ==
Date: Thurs, Jan 30 2014 10:29 am
From: "Osmium"


<mary8shtr@gmail.com> wrote:

> Hi.I joined recently to this group .I want write a program in c++
> language.one program in c++ that receive two char array from user and
> print all of state built by this tow arryas.for example users enter "abc"
> and "mn".program should show abcmn , abmnc , amnbc , mnabc ,mabcn ,manbc,
> mabnc , ambnc ,ambcn ,abmcn as output.pleas answer me.I very thought on
> this solution.but I couldn't solve it.and i need it early.I thanks very
> much if anyone answer me faster.

I may not understand your problem. Forging ahead.

I plugged <permutations c++> into google and got a lot of results. One of
the early ones that might be at an appropriate level is this one:

http://www.codeproject.com/Articles/4895/Permutations-in-C






== 3 of 5 ==
Date: Thurs, Jan 30 2014 11:14 am
From: bblaz


On 01/30/14 16:34, mary8shtr@gmail.com wrote:
> Hi.I joined recently to this group .I want write a program in c++ language.one program in c++ that receive two char array from user and print all of state built by this tow arryas.for example users enter "abc" and "mn".program should show abcmn , abmnc , amnbc , mnabc ,mabcn ,manbc, mabnc , ambnc ,ambcn ,abmcn as output.pleas answer me.I very thought on this solution.but I couldn't solve it.and i need it early.I thanks very much if anyone answer me faster.
>

#include <iostream>
#include <algorithm>
#include <string>

int main(int argc, char* argv[]) {
if (argc != 3) {
std::cerr << "Usage: ./permutations input1 input2 \n";
std::exit(1);
}

std::string s = std::string(argv[1]) + std::string(argv[2]);

do {
std::cout << s << " ";
} while (std::next_permutation(s.begin(), s.end()));
std::cout << std::endl;

return 0;
}




== 4 of 5 ==
Date: Thurs, Jan 30 2014 1:16 pm
From: Jorgen Grahn


On Thu, 2014-01-30, bblaz wrote:
> On 01/30/14 16:34, mary8shtr@gmail.com wrote:

>> Hi.I joined recently to this group .I want write a program in c++
...

> std::string s = std::string(argv[1]) + std::string(argv[2]);
>
> do {
> std::cout << s << " ";
> } while (std::next_permutation(s.begin(), s.end()));

That doesn't seem to produce the result he wants -- in his examples
the elements of each original string never got permutated.

Let me try ... say the input strings are A and B.

You can construct a valid result by popping an element off A, another
one from B, ... and so on, A.size() + B.size() times. And you can do
that many different ways -- there are A.size() + B.size() decisions to
make, restricted by the fact that A.size() times you have to decide
"I'll pop from A". The rest of the time you need to pop from B.

I think I see a solution, so I'll stop there. Hint: next_permutation()
can still be used, but on the decision chain rather than the strings
themselves.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .




== 5 of 5 ==
Date: Thurs, Jan 30 2014 6:23 pm
From: sg


Am 30.01.2014 22:16, schrieb Jorgen Grahn:
> On Thu, 2014-01-30, bblaz wrote:
>> On 01/30/14 16:34, mary8shtr@gmail.com wrote:
>
>>> Hi.I joined recently to this group .I want write a program in c++
> ...
>
>> std::string s = std::string(argv[1]) + std::string(argv[2]);
>>
>> do {
>> std::cout << s << " ";
>> } while (std::next_permutation(s.begin(), s.end()));
>
> That doesn't seem to produce the result he wants -- in his examples
> the elements of each original string never got permutated.
>
> Let me try ... say the input strings are A and B.
>
> You can construct a valid result by popping an element off A, another
> one from B, ... and so on, A.size() + B.size() times. And you can do
> that many different ways -- there are A.size() + B.size() decisions to
> make, restricted by the fact that A.size() times you have to decide
> "I'll pop from A". The rest of the time you need to pop from B.
>
> I think I see a solution, so I'll stop there. Hint: next_permutation()
> can still be used, but on the decision chain rather than the strings
> themselves.

Good guess (w.r.t. to what the OP wants)!
Good solution (w.r.t. to the guessed question)!
:-)

> /Jorgen






==============================================================================
TOPIC: How does the name lookup work in this case?
http://groups.google.com/group/comp.lang.c++/t/f7e465d3b9e6c21f?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 30 2014 10:09 am
From: Peter


> > In order for the compiler to find it I have to qualify it fully as
>
> > Foo::Foo::x despite the "using namespace Foo;" line.
>
>
>
> That's not full qualification, and Visual C++ still emits the diagnostic
>
> above.
>
>
>
> Full qualification is
>
>
>
> ::Foo::Foo::x;
>
>
>
> and this is accepted by Visual C++.
>

Perhaps a silly question, but what's the difference
between ::Foo::Foo::x and Foo::Foo::x here?
I thought they were equal in this context.

> I think the ambiguity is real and that the g++ failure to diagnose it is
>
> a compiler bug. I could be wrong. But, since the two compilers disagree,
>
> at least one of Visual C++ and g++ has a bug here. ;-)
>

I also think this may be a g++ bug (unless there's yet another
obscure C++ rule according to which the compiler isn't supposed to
interpret Foo::x as static member of class Foo in this case).







==============================================================================
TOPIC: Hey, talk.origins crank:
http://groups.google.com/group/comp.lang.c++/t/f20d73dd3f975d02?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Jan 30 2014 7:02 pm
From: CHAIRMAN THRINAXODON OF THE COMMUNIST PARTY OF CANADA


http://thrinaxodon.wordpress.com
--
Thrinaxodon, The Ultimate Defender of USENET




==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en

To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

No comments: