Monday, December 29, 2008

comp.lang.c++ - 10 new messages in 6 topics - digest

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

comp.lang.c++@googlegroups.com

Today's topics:

* Question on using volatile in a return type - 4 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/6e1fac2968bd4ab9?hl=en
* map of std::complex - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/926f261ed6642f3b?hl=en
* Using std::lexicographical_compare with ignore case equality doesn't always
work - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/dc61ed435800deb4?hl=en
* Questionable code example in C++ FAQ Lite? - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/db4c3e1f63ad2629?hl=en
* 有無人知道IT界邪童丘的事跡? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/8b8604ceda56f3cc?hl=en
* Can I get a ptr to an element from an stl vector iterator? - 1 messages, 1
author
http://groups.google.com/group/comp.lang.c++/t/262bb7f778c645b8?hl=en

==============================================================================
TOPIC: Question on using volatile in a return type
http://groups.google.com/group/comp.lang.c++/t/6e1fac2968bd4ab9?hl=en
==============================================================================

== 1 of 4 ==
Date: Sun, Dec 28 2008 4:09 pm
From: peter koch


> Hello all,
>
> actually I am asking as well about semantics and best practices...
>
> To start with, I am waiting on a condition variable (in a loop that is).
> The actual condition is a bool flag located elsewhere, which is
> to be passed in as a function parameter. So the correct type would be
> "volatile bool&"
>
> void func1 (volatile bool& flag) {
> // init...
>
> while (!flag && !err)
> err = pthread_cond_wait (&cond, &mutex);
>
> // ...
>
> }
>
> The "volatile" should give the compiler a hint not to employ optimisations
> but fetch the value from the original location, where it may have been changed
> by another thread meanwhile -- is this correct?
>
> And: does the flag referred to have to be declared as volatile at the original
> location? (usually somewhere in a class?). Or is it sufficient to define the
> reference as volatile bool& ?
>
> Now, assumed I want to use a functor instead of the bool flag.
> What would be the correct and the "best" way to define it?
>
> class Check1 {
> bool operator() () { ... }
>
> }
>
> class Check2 {
> volatile bool operator() () { ... }
>
> }
>
> class Check3 {
> volatile bool& operator() () { ... }
>
> }
>
> My understanding is that for Check3 the "volatile" is necessary, is this
> correct? But Check1 should be ok, because it's returning a value and it will
> actually be re-invoked in each loop iteration?
>
> And besides, would you consider the definition within Check2 good practice,
> bad practice, expressive, superfluous, ....?

Any use of volatile wrt threading is unneeded and bad practice (even
if you use a compiler where volatile has an established meaning
threadwise).

/Peter


== 2 of 4 ==
Date: Sun, Dec 28 2008 4:58 pm
From: Ichthyostega


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>> The "volatile" should give the compiler a hint not to employ optimisations
>> but fetch the value from the original location, where it may have been
>> changed by another thread meanwhile -- is this correct?

peter koch schrieb:
> Any use of volatile wrt threading is unneeded and bad practice (even if you
> use a compiler where volatile has an established meaning threadwise).
>

Hi Peter,

actually, your response confuses me somewhat. Could you please point me to
any resource explaining why this would be the case?

just to quote two:

http://www.ddj.com/cpp/184403766
http://blog.emptycrate.com/node/272

...which both seem to contradict your statement.
Probably I'm missing something very basic here?

Hermann

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJWCDEZbZrB6HelLIRAsk0AJ44SkaHpt16o4Hd29NY4Aqjr80e2wCgpIsp
BcMTwvS4zpGEmuJsApnmTpo=
=UqZn
-----END PGP SIGNATURE-----


== 3 of 4 ==
Date: Sun, Dec 28 2008 6:31 pm
From: blargg.h4g@gishpuppy.com (blargg)


Ichthyostega wrote:
[...]
> void func1 (volatile bool& flag) {
> // init...
>
> while (!flag && !err)
> err = pthread_cond_wait (&cond, &mutex);
>
> // ...
> }
>
> The "volatile" should give the compiler a hint not to employ
> optimisations but fetch the value from the original location, where
> it may have been changed by another thread meanwhile -- is this
> correct?

Correct. Like const, the const/volatile in references/pointers to
const/volatile affects what can be done via the reference/pointer.

int i;
const int& c = i;

c = 1; // error
i = 2; // OK

volatile int& v = i;
v = 1;
v = 2; // generate code must write to v twice
i = 3; // generated code can eliminate this write to i
i = 4;

> And: does the flag referred to have to be declared as volatile at
> the original location? (usually somewhere in a class?). Or is it
> sufficient to define the reference as volatile bool& ?

Original object can be non-volatile, just as with const.

> Now, assumed I want to use a functor instead of the bool flag.
> What would be the correct and the "best" way to define it?

To be equivalent, use volatile appropriately on any objects the
functor uses.

> class Check1 {
> bool operator() () { ... }
> }
>
> class Check2 {
> volatile bool operator() () { ... }
> }
>
> class Check3 {
> volatile bool& operator() () { ... }
> }
>
> My understanding is that for Check3 the "volatile" is necessary, is this
> correct? But Check1 should be ok, because it's returning a value and it will
> actually be re-invoked in each loop iteration?

Depends on what the ... is. Assuming something like

class Check1 {
volatile bool& b;
bool operator() () { return b; }
};

Then it's fine, since in accessing b the compiler is forced to read.
The same would work for the other two as well, with their unnecessary
volatile and bool.

If you instead had a reference-to-non-volatile,

class Check1 {
bool& b;
bool operator() () { return b; }
};

Check1 and Check2 could fail, since the compiler could avoid
re-reading the object referred to by b. But Check3 would work, since
the caller would be accessing the object via a volatile path:

class Check3 {
bool& b;
volatile bool& operator() () { return b; }
};

void func1 (Check3 flag)
{
while (!flag() && !err)
...
}

> And besides, would you consider the definition within Check2 good practice,
> bad practice, expressive, superfluous, ....?

From what little I know about multi-threaded (including multi-core and
multi-processor) coding, volatile alone is insufficient in most cases,
since in the absence of thread synchronization operations, the order
of memory writes in one thread can differ from the order they're seen
by another thread. That is, I believe that something like

volatile sig_atomic_t x, y;

void thread_1()
{
while ( x == 0 ) { }
cout << y;
}

void thread_2()
{
y = 1;
x = 1;
}

could print 0, even though thread_2 writes to y first (through a
volatile variable). What do you know, the example on Wikipedia is the
same: http://en.wikipedia.org/wiki/Memory_barrier

BTW, PGP-signing your messages adds lots of cruft that clutters your
postings.


== 4 of 4 ==
Date: Mon, Dec 29 2008 12:11 am
From: Paavo Helde


Ichthyostega <Ichthyostega@web.de> kirjutas:

>
> peter koch schrieb:
>> Any use of volatile wrt threading is unneeded and bad practice (even
>> if you use a compiler where volatile has an established meaning
>> threadwise).

> actually, your response confuses me somewhat. Could you please point
> me to any resource explaining why this would be the case?
>
> just to quote two:
>
> http://www.ddj.com/cpp/184403766
> http://blog.emptycrate.com/node/272
>
> ...which both seem to contradict your statement.

The first one discusses how to recycle 'volatile' to do some compile-time
checks. The second is a negative and non-portable example, as the author
admits in the end of the page.

'volatile' is needed for programming memory-mapped peripheral devices. If
you don't do this, you can forget about volatile! This topic has been
covered here many times.

Paavo


==============================================================================
TOPIC: map of std::complex
http://groups.google.com/group/comp.lang.c++/t/926f261ed6642f3b?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 4:45 pm
From: blargg.h4g@gishpuppy.com (blargg)


Juha Nieminen wrote:
> Joe Smith wrote:
> > if (lhs.real()<rhs.real()) return true;
> > else if (lhs.real()==rhs.real()&& lhs.imag()<rhs.imag()) return true;
> > return false;
>
> Wouldn't that be the same as:
>
> return lhs.real() < rhs.real() ||
> (lhs.real() == rhs.real() && lhs.imag() < rhs.imag());

Yes. I think Joe Smith was attempting a more general pattern where the
number of members can vary, since using a single expression for
everything can get unwieldy. Something like this:

struct T
{
A a;
B b;
...
};

struct Comp
{
bool operator () ( T const& x, T const& y ) const
{
if ( x.a < y.a ) return true;
if ( x.a > y.a ) return false;

if ( x.b < y.b ) return true;
if ( x.b > y.b ) return false;

...

return false;
}
};

But of course making a map of something with floating-point keys is a
bound to cause problems if the keys are generated by more than one
calculation.

==============================================================================
TOPIC: Using std::lexicographical_compare with ignore case equality doesn't
always work
http://groups.google.com/group/comp.lang.c++/t/dc61ed435800deb4?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 4:51 pm
From: blargg.h4g@gishpuppy.com (blargg)


Alex Buell wrote:
[...]
> I've now switched to using this:
>
> #include <string.h>
> #include <string>
>
> inline int strcasecmp(const std::string& s1, const std::string& s2)
> {
> return strcasecmp(s1.c_str(), s2.c_str());
> }
>
> This leverages C++'s ability to overload functions and works better.

Actually, it looks more like it leverages C++'s ability to cause a stack
overflow due to infinite recursion. strcasecmp isn't part of ISO C++, so
on plenty of compilers, this function will simply call itself.

> stricmp() isn't standard whilst strcasecmp() is standard ANSI/ISO. Some
> posters have mentioned using stricmp() instead of strcasecmp(), which
> happens not to be the correct answer. Why?

As far as I can tell, neither are part of standard C++.

==============================================================================
TOPIC: Questionable code example in C++ FAQ Lite?
http://groups.google.com/group/comp.lang.c++/t/db4c3e1f63ad2629?hl=en
==============================================================================

== 1 of 2 ==
Date: Sun, Dec 28 2008 5:35 pm
From: "jason.cipriani@gmail.com"


On Dec 28, 10:07 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> James Kanze wrote:
> > On Dec 28, 10:26 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> >> Consider the code example here:
>
> >>http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
>
> >> It needlessly allocates an object dynamically and, what's
> >> worse, it never deletes it.
>
> > So what? It's only an example, displaying a particular problem.
>
> Can't you read the entire post before answering? I explained the
> reason why I consider it a dubious example.
>
> >> Let me emphasize that I understand perfectly that this is done
> >> to keep the example short and simple, and that I understand
> >> that *how* the object is created is completely irrelevant with
> >> respect to what the example is trying to show. (In other
> >> words, the allocation of the object is not the point of the
> >> example, but how the object is used in the subsequent lines.)
>
> > So what's the point?
>
> Do you only read one paragraph at a time when you answer to someone's
> post?
>
> >> However, given that, AFAIK, this FAQ tries to teach good
> >> programming practices in C++, this is a horrible example of
> >> that.
>
> > In what way?
>
> It seems to be so (given that I explain it immediately after that
> paragraph).
>
> > Even beginning programmers write code more complex than the
> > example. And are capable of understanding that it is only an
> > example.
>
> What does it even mean that "it is only an example"? Exactly which
> part of it is "only an example" which should not be taken literally? All
> of it? Part of it? Which part?
>
> Exactly how is the beginner programmer supposed to know that "btw,
> this part is only for the sake of an example; you should not do this in
> actual code"? Wouldn't it be better to simply avoid giving as example
> code which should not be written?

While I kind of agree the example has some faults, it's a good example
of what it's trying to show, it's probably the case that a beginning
programmer will learn the correct way to create and destroy objects
sooner or later -- likely sooner. Also, a programmer who is reading
about hidden base members may likely have seen new/delete before and
is probably far enough along to not be corrupted by the example.

In any case a single example that's missing a delete is not going to
send a beginning programmer down a long path of suffering, failure,
and humiliation on their way to learning C++ -- there are other things
that will send them down that path far more effectively (such as
posting questions to this newsgroup :-).

Also, the memory is freed when the process ends. Unless the destructor
has side effects outside the process (e.g. committing data to disk or
affecting external hardware), it's technically not really an issue,
even if it is a bit dubious looking.

Jason


== 2 of 2 ==
Date: Sun, Dec 28 2008 10:07 pm
From: alfps


On 28 Des, 11:26, alfps <alf.p.steinb...@gmail.com> wrote:
> I'm sure Marshall will fix things if he's able to.

Marshall writes that he'll add a 'delete' and "please pass on my very
best to Juha Nieminen".

Cheers & hth.,

- Alf

==============================================================================
TOPIC: 有無人知道IT界邪童丘的事跡?
http://groups.google.com/group/comp.lang.c++/t/8b8604ceda56f3cc?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 6:13 pm
From: it_daemon@hotmail.com


有無人知道IT界邪童丘的事跡?
http://www.geocities.com/it_super_manager

==============================================================================
TOPIC: Can I get a ptr to an element from an stl vector iterator?
http://groups.google.com/group/comp.lang.c++/t/262bb7f778c645b8?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 11:06 pm
From: blargg.h4g@gishpuppy.com (blargg)


Bo Persson wrote:
> Steve555 wrote:
> > Of course I should have tried &*iter, but I'd got side-tracked and
> > reasoned that as iter is a kind of pointer,
>
> It is actually the other way round - a pointer is a kind of random
> access iterator!
>
> > I could just cast:
> > myStructPtr = (myStruct*)iter
>
> Casts are most often bad, and tells the compiler to "just shut up and
> do it!". Whether it actually works or not...

Especially old-style casts. If an inexperienced C++ programmer feels he
must cast, he should stick to static_cast unless he knows for certain.
Even then, static_cast requires care when downcasting.


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

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: