Sunday, December 28, 2008

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

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

comp.lang.c++@googlegroups.com

Today's topics:

* Using std::lexicographical_compare with ignore case equality doesn't always
work - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/dc61ed435800deb4?hl=en
* www.voguetouch.com sell nike shoes,tshirt,ugg boots,handbags and so on - 1
messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/4ceb0bc3fba7290d?hl=en
* Sets in C++ - 4 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/5d3d498a2fe8b146?hl=en
* breaking circular dependency?! - 7 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/f5c736d548652ca1?hl=en
* bit fields and data structure - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/f71b2b373b5ef270?hl=en
* Error using STL function copy - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/020430359ddd5edc?hl=en
* Puzzled as to why this works. Inheritance question - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/d4d2e517c330b01e?hl=en
* map of std::complex - 4 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/926f261ed6642f3b?hl=en
* l-values and r-values - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/6179b8a03e7ae085?hl=en
* Question on using volatile in a return type - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/6e1fac2968bd4ab9?hl=en

==============================================================================
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 3 ==
Date: Sun, Dec 28 2008 7:33 am
From: "Daniel T."


In article <20081228134414.4b9220f0@lithium.local.net>,
Alex Buell <alex.buell@munted.org.uk> wrote:

> The short snippet below demonstrates the problem I'm having with
> std::lexicographical_compare() in that it does not reliably work!
>
> #include <iostream>
> #include <vector>
> #include <ctype.h>
>
> bool compare_ignore_case_equals(char c1, char c2)
> {
> return toupper(c1) == toupper(c2);
> }
>
> bool compare_ignore_case_less(char c1, char c2)
> {
> return toupper(c1) < toupper(c2);
> }
>
> int main(int argc, char *argv[])
> {
> std::vector<std::string> args(argv + 1, argv + argc);
> const char *words[] =
> {
> "add", "del", "new", "help"
> };
>
> std::vector<std::string> list(words, words + (sizeof words / sizeof
> words[0]));
> std::vector<std::string>::iterator word = list.begin();
> while (word != list.end())
> {
> std::cout << "Testing " << *word << " = " << args[0];
> if (std::lexicographical_compare(
> word->begin(), word->end(),
> args[0].begin(), args[0].end(),
> compare_ignore_case_equals))
> {
> std::cout << " found!\n";
> break;
> }
>
> std::cout << "\n";
> word++;
> }
> }

Why are you using compare_ignore_case_equals as your binary predicate?

--
Perfection is achieved, not when there is nothing more to add,
but when there is nothing left to take away.
-- Antoine de Saint-Exupery


== 2 of 3 ==
Date: Sun, Dec 28 2008 9:51 am
From: Pete Becker


On 2008-12-28 10:12:46 -0500, Alex Buell <alex.buell@munted.org.uk> said:

> On Sun, 28 Dec 2008 09:09:32 -0500, I waved a wand and this message
> magically appears in front of Pete Becker:
>
>>> if (std::lexicographical_compare(
>>> word->begin(), word->end(),
>>> args[0].begin(), args[0].end(),
>>> compare_ignore_case_equals))
>>
>> First, remove compare_ignore_case_equals and try again. You'll get
>> similar problems. Then read about lexicographical_compare and what
>> its return value means.
>
> 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.
>
> stricmp() isn't standard whilst strcasecmp() is standard ANSI/ISO.

No, it's not. It's Unix, if I remeber correctly. But I think I didn't
make my point clearly enough. The problem isn't fundamentally in the
predicate. So drop the predicate and use the default predicate until
you understand what lexicographical_compare does.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

== 3 of 3 ==
Date: Sun, Dec 28 2008 10:07 am
From: Alex Buell


On Sun, 28 Dec 2008 12:51:36 -0500, I waved a wand and this message
magically appears in front of Pete Becker:

> > This leverages C++'s ability to overload functions and works better.
> >
> > stricmp() isn't standard whilst strcasecmp() is standard ANSI/ISO.
>
> No, it's not. It's Unix, if I remeber correctly. But I think I didn't
> make my point clearly enough. The problem isn't fundamentally in the
> predicate. So drop the predicate and use the default predicate until
> you understand what lexicographical_compare does.

strcasecmp() is actually defined in the POSIX standards. But I will
look again at std::lexicograpical_compare() when I get some time. The
program works well enough with strcasecmp().
--
http://www.munted.org.uk

Fearsome grindings.


==============================================================================
TOPIC: www.voguetouch.com sell nike shoes,tshirt,ugg boots,handbags and so on
http://groups.google.com/group/comp.lang.c++/t/4ceb0bc3fba7290d?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 7:43 am
From: "www.voguetouch.com"


cheap nike shoes: WWW(VOGUETOUCH)COM
We are wholesaler of Nike Jordan and Other Shoes in China. We are a
professional exporting company in china. We supply many kinds of
Shoes, such as Nike Shoes, Jordan 1-23, Air Jordan, AF1, DUNK, Air max
series etc. Most of them are in stock and can be supplied surely on
time. All these shoes are packed with original-boxes and cards
our price $33jordan shoes,$15tshirt,15sunglasess, $13cap,$33jean,
$35bag

our website:
WWW(VOGUETOUCH)COM
MSN:voguetouch01@msn.com

==============================================================================
TOPIC: Sets in C++
http://groups.google.com/group/comp.lang.c++/t/5d3d498a2fe8b146?hl=en
==============================================================================

== 1 of 4 ==
Date: Sun, Dec 28 2008 8:06 am
From: "Aaron Gray"


I want to represent a set in C++ that is indexed by number. I need to be
able to do unions and stuff between two existing sets forming a new set. I
have looked at 'bitset' but its a bit lame then theres vector<bool> but I
cannot find ant good documentation on either.

Help and suggestions most welcome,

Aaron


== 2 of 4 ==
Date: Sun, Dec 28 2008 8:19 am
From: Obnoxious User


On Sun, 28 Dec 2008 16:06:56 +0000, Aaron Gray wrote:

> I want to represent a set in C++ that is indexed by number. I need to be
> able to do unions and stuff between two existing sets forming a new set.
> I have looked at 'bitset' but its a bit lame then theres vector<bool>
> but I cannot find ant good documentation on either.
>
> Help and suggestions most welcome,
>


std::set ?

--
OU


== 3 of 4 ==
Date: Sun, Dec 28 2008 8:46 am
From: Kai-Uwe Bux


Aaron Gray wrote:

> I want to represent a set in C++ that is indexed by number.

Indexed? Do you mean that the elements of the set are integers?

> I need to be
> able to do unions and stuff between two existing sets forming a new set. I
> have looked at 'bitset' but its a bit lame then theres vector<bool> but I
> cannot find ant good documentation on either.

The standard documents both.

> Help and suggestions most welcome,

There is a fundamental difference between sets of (comparatively small)
known maximum size and sets of arbitrary large size. The container
std::bitset<> is for the former, the container std::vector<bool> is of
questionable value, and std::set<int> is the standard choice when the size
is unknown. You could also use std::vector<int> (or std::deque<int>) and
keep the sequence sorted. It is easy to use binary_search<> to test for
elements and you can find the union or intersection of two such sets in
time linear in the total number of elements (probably best possible). The
algorithms std::set_union, std::set_difference, std::intersection, and
std::set_symmetric_difference make that fairly easy. Complements are more
tricky with all dynamic data structures.

I would recommend devising a class int_set with a minimal interface (just
enough for your application) and a straight forward initial implementation.
Make sure that it works by writing a bunch of tests. Then, you can replace
the implementation (i.e., replace the internal data structure) and try to
make it more efficient if a profiler shows the need. Without further
information, it is impossible to tell a priory which data structure is best
for your application.


Best

Kai-Uwe Bux


== 4 of 4 ==
Date: Sun, Dec 28 2008 8:58 am
From: Erik Wikström


On 2008-12-28 17:19, Obnoxious User wrote:
> On Sun, 28 Dec 2008 16:06:56 +0000, Aaron Gray wrote:
>
>> I want to represent a set in C++ that is indexed by number. I need to be
>> able to do unions and stuff between two existing sets forming a new set.
>> I have looked at 'bitset' but its a bit lame then theres vector<bool>
>> but I cannot find ant good documentation on either.
>>
>> Help and suggestions most welcome,
>>
> std::set ?

And the std::set_* functions from <algorithm>.

To find documentation try googling for 'bitset c++'. If you use a bitset
(I would not use vector<bool> since it is kind of special) the set
operations can be performed using bit operations, or is the union, and
is the intersection, xor the symmetric difference.

--
Erik Wikström

==============================================================================
TOPIC: breaking circular dependency?!
http://groups.google.com/group/comp.lang.c++/t/f5c736d548652ca1?hl=en
==============================================================================

== 1 of 7 ==
Date: Sun, Dec 28 2008 9:38 am
From: Oliver Kowalke


Hi,
how could following problem be solved (not the same base class)?

// A.h

class A
{
private:
   const X move_()
   { ... }

public:
   const B f()
   { return B( move_() ); }
};


// B.h

class B
{
private:
   const X move_()
   { ... }

public:
   const A f()
   { return A( move_() ); }
};

== 2 of 7 ==
Date: Sun, Dec 28 2008 9:52 am
From: Rolf Magnus


Oliver Kowalke wrote:

> Hi,
> how could following problem be solved (not the same base class)?

What base class?

> // A.h
>
> class A
> {
> private:
> const X move_()
> { ... }
>
> public:
> const B f()
> { return B( move_() ); }
> };
>
>
> // B.h
>
> class B
> {
> private:
> const X move_()
> { ... }
>
> public:
> const A f()
> { return A( move_() ); }
> };

Don't implement the functions in the header, but in the implementation file.
Then put a forward declaration before the class definition.


== 3 of 7 ==
Date: Sun, Dec 28 2008 10:00 am
From: zr


On Dec 28, 7:38 pm, Oliver Kowalke <oliver.kowa...@gmx.de> wrote:
> Hi,
> how could following problem be solved (not the same base class)?
>
> // A.h
>
> class A
> {
> private:
>    const X move_()
>    { ... }
>
> public:
>    const B f()
>    { return B( move_() ); }
>
> };
>
> // B.h
>
> class B
> {
> private:
>    const X move_()
>    { ... }
>
> public:
>    const A f()
>    { return A( move_() ); }
>
> };
>
>

see http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.11


== 4 of 7 ==
Date: Sun, Dec 28 2008 10:31 am
From: Oliver Kowalke


Rolf Magnus wrote:

> Oliver Kowalke wrote:
>
>> Hi,
>> how could following problem be solved (not the same base class)?
>
> What base class?

I mean I don't want to have a (shared) base class (as a suggestion)

>> // A.h
>>
>> class A
>> {
>> private:
>> const X move_()
>> { ... }
>>
>> public:
>> const B f()
>> { return B( move_() ); }
>> };
>>
>>
>> // B.h
>>
>> class B
>> {
>> private:
>> const X move_()
>> { ... }
>>
>> public:
>> const A f()
>> { return A( move_() ); }
>> };
>
> Don't implement the functions in the header, but in the implementation
> file. Then put a forward declaration before the class definition.

forward declarations work for references or pointer in the header - doesn't
the compiler need to know the size of A / B in the header because it A and
B are returned by value and not as refernce or pointer?


== 5 of 7 ==
Date: Sun, Dec 28 2008 10:32 am
From: Oliver Kowalke


zr wrote:
> see
> http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.11
A and B are returned by value and not as references or pointers.


== 6 of 7 ==
Date: Sun, Dec 28 2008 10:44 am
From: Rolf Magnus


Oliver Kowalke wrote:

>> Don't implement the functions in the header, but in the implementation
>> file. Then put a forward declaration before the class definition.
>
> forward declarations work for references or pointer in the header -
> doesn't the compiler need to know the size of A / B in the header because
> it A and B are returned by value and not as refernce or pointer?

No.


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


Rolf Magnus wrote:
> Oliver Kowalke wrote:
[...]
[simplified code]
> > // A.h
> > struct A {
> > const X move_() { ... }
> > const B f() { return B( move_() ); }
> > };
> >
> >
> > // B.h
> > struct B {
> > const X move_() { ... }
> > const A f() { return A( move_() ); }
> > };
>
> Don't implement the functions in the header, but in the implementation file.
> Then put a forward declaration before the class definition.

And if they must be inline, do this (with type X defined appropriately):

// A.h
struct B;

struct A {
const X move_() { ... }
const B f();
};

#include "B.h"

inline const B A::f() { return B( move_() ); }

// B.h
struct A;

struct B {
const X move_() { ... }
const A f();
};

#include "A.h"

inline const A B::f() { return A( move_() ); }

With proper include guards for A.h and B.h, the circular inclusion will
work properly.

==============================================================================
TOPIC: bit fields and data structure
http://groups.google.com/group/comp.lang.c++/t/f71b2b373b5ef270?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 9:40 am
From: ma740988


On Dec 28, 8:29 am, James Kanze <james.ka...@gmail.com> wrote:

> In some ways, it is a solution looking for a
> problem.  It certainly provides something more directly readable
> than the current situation, and it provides a portable syntax.
> But hardware I/O registers are by their very nature unportable,
> so the portable syntax doesn't buy you much.  And it's not as if
> bit shifting etc. cause any real problems.
>
Fair enough! I was headed down the path with sets_this_variable and
gets_this_variable with the bit fiddling done within the methods. At
some point I thought there has to be a better way :) then I ran across
this article:

http://www.artima.com/cppsource/safelabels.html
A novel idea with regards to individual bits but it doesn't appear to
address a range of bits.

Oh well
Thanks

==============================================================================
TOPIC: Error using STL function copy
http://groups.google.com/group/comp.lang.c++/t/020430359ddd5edc?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 11:53 am
From: "g3rc4n@gmail.com"


On Dec 28, 3:18 pm, arkady.karp...@gmail.com wrote:
> Hello,
>
> During compilation of code :
> std::copy(AgentID_To_AgentStruct.begin(),AgentID_To_AgentStruct.end
> (),Local_AgentID_To_AgentStruct.begin());
>
> I got error
>
> Error   125     error C2582: 'operator =' function is unavailable in
> 'std::pair<_Ty1,_Ty2>'    D:\Program Files\Microsoft Visual Studio 8\VC
> \include\xutility       2266
>
> I am using VC7++.
>
> Thanks
>
> Arkady

sounds like something can't be copied, overload operator= for the
elements of Local_AgentID_To_AgentStruct

==============================================================================
TOPIC: Puzzled as to why this works. Inheritance question
http://groups.google.com/group/comp.lang.c++/t/d4d2e517c330b01e?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 1:37 pm
From: Paavo Helde


Angus <anguscomber@gmail.com> kirjutas:

> I have the following classes:
>
> class call {
> public:
> long GetCallID();
> void SetCallID(long callid);
>
> private:
> long m_CallID;
> };
>
> class tapicall : public call
> {
> public:
> long GetTapiID();
> void SetTapiID(long tapiid);
>
> private:
> long m_TapiID;
> };
>
>
> class iface
> {
> public:
> call* FindCallByID(long callid);
> void CreateNewCall(long callid);
> void DeleteCall(long callid);
>
> private:
> std::list<call*> m_calllist;
>
> };
>
> Implementation here:
> #include "call.h"
>
> long call::GetCallID(){
> return m_CallID;
> }
>
> void call::SetCallID(long callid){
> m_CallID = callid;
> }
>
> long tapicall::GetTapiID(){
> return m_TapiID;
> }
>
> void tapicall::SetTapiID(long tapiid){
> m_TapiID = tapiid;
> }
>
> call* iface::FindCallByID(long callid){
> std::list<call*>::const_iterator it;
> for(it = m_calllist.begin(); it != m_calllist.end(); ++it){
> if((*it)->GetCallID() == callid)
> return *it;
> }
> return 0;
> }
>
> void iface::CreateNewCall(long callid){
> call* pCall = new call;
> pCall->SetCallID(callid);
> m_calllist.push_back(pCall);

Here, only call objects are created and pushed to the list. No tapicall
object is created anywhere.

> }
>
> void iface::DeleteCall(long callid){
> //do later
> }
>
>
> Then if I do this (in order as below):
>
> void CInherittestDlg::OnOK()
> {
> m_iface.CreateNewCall(1);
> }
>
> void CInherittestDlg::OnBtnSet()
> {
> tapicall* ptcall = reinterpret_cast<tapicall*>(m_iface.FindCallByID
> (1));

As no tapicall objects have been ever created, this reinterpret_cast
produces undefined behavior (unless the pointer is NULL).

> if(ptcall) {
> ptcall->SetTapiID(3);
> }
> }
>
> void CInherittestDlg::OnBtnGet()
> {
> long tapiid;
> tapicall* ptcall = reinterpret_cast<tapicall*>
(m_iface.FindCallByID
> (1));
> if(ptcall) {
> tapiid=ptcall->GetTapiID();
> }
> }
>
> Then I get the correct value back.
>
> My understanding problem is that m_iface.FindCallByID returns a
> call*. A call* stored in the std::list has only enough memory
> reserved to be a call*

True, but irrelevant. What counts it the size of the object the call*
pointer points to. A valid call* pointer can point either to a call
object or a tapicall object (or be NULL). If there were some entries
created as 'new tapicall' and reinterpret_cast were used only on those
entries, then everything would be fine.

>
> And we simply cast to a tapicall* and get the 'extra' bit which is the
> TapiID. How does this work at a low level? Surely what is stored in
> the iface list is only a call*?

True, but irrelevant. The objects themselves are not part of the list.

>
> Puzzled as to how it works.

As it stands in your example, it doesn't.

Regards
Paavo

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

== 1 of 4 ==
Date: Sun, Dec 28 2008 2:54 pm
From: Mohamed Ali


I need to create a map:
map<complex<int>,complex<double> >
But it generate an error due to operator != and < ?
Am I supposed to overload != and < operator for std::complex and How?

Thanks for help


== 2 of 4 ==
Date: Sun, Dec 28 2008 3:13 pm
From: "Joe Smith"

"Mohamed Ali" <chermi.ma@gmail.com> wrote in message
news:ea197a0d-5038-4d0c-b904-efb04527e255@q26g2000prq.googlegroups.com...
>I need to create a map:
> map<complex<int>,complex<double> >
> But it generate an error due to operator != and < ?
> Am I supposed to overload != and < operator for std::complex and How?
>
> Thanks for help

You could use code like the following:

template<typename T>
struct complex_less
{
bool operator() (const std::complex<T>& lhs, const std::complex<T>& rhs)
{
if (lhs.real()<rhs.real()) return true;
else if (lhs.real()==rhs.real()&& lhs.imag()<rhs.imag()) return true;
return false;
}
};

std::map<std::complex<int>,std::complex<double>, complex_less<int> > t;


== 3 of 4 ==
Date: Sun, Dec 28 2008 4:01 pm
From: peter koch


On 28 Dec., 23:54, Mohamed Ali <chermi...@gmail.com> wrote:
> I need to create a map:
> map<complex<int>,complex<double> >

Why? I've never seen complex used as key, and I also find complex<int>
slightly unusual. This does not exclude the possibility that your
design is wrong, of course.

> But it generate an error due to operator != and < ?

I can't imagine it complaining about a missing operator !=. But you
need to supply an operator <, as complex numbers aren't ordered.

> Am I supposed to overload != and < operator for std::complex and How?

You are supposed to create an ordering function. As to how, I believe
you should do some of your work yourself and search for the answer in
your textbook, the net (e.g. the C++ FAQ) or in your compilers
documentation.

/Peter


== 4 of 4 ==
Date: Sun, Dec 28 2008 4:08 pm
From: Juha Nieminen


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());

==============================================================================
TOPIC: l-values and r-values
http://groups.google.com/group/comp.lang.c++/t/6179b8a03e7ae085?hl=en
==============================================================================

== 1 of 1 ==
Date: Sun, Dec 28 2008 3:55 pm
From: "Victor Bazarov"


Ali Karaali wrote:
> I want to ask another question that related the topic.
>
> One of the important difference between C and C++ is
> prefix ++ operator. The operator doesn't yield an l-value
> in C but in C++ it yields a l-value.
>
> I tried to overload the prefix ++ oprator for that class;
>
> class MyInt
> {
> int m_i;
>
> friend ostream & operator<< (ostream &, const MyInt &);
>
> public:
>
> MyInt(int i)
> :
> m_i(i)
> {}
>
> MyInt(const MyInt & r)
> {
> m_i = r.m_i;
> }
>
> MyInt & operator+= (const MyInt & anoth)
> {
> m_i += anoth.m_i;
> return *this;
> }
>
> MyInt operator++ (int);
>
> MyInt & MyInt::operator ++()
> {
> return *this += 1;
> }
> };
>
> MyInt MyInt::operator++ ( int )
> {
> MyInt m_r( *this );
> ++*this;
>
> return m_r;
> }
>
> MyInt operator+ (const MyInt & lefts, const MyInt & rights)
> {
> MyInt result = lefts;
> result += rights;
> return result;
>
> // Or
> // return MyInt( lefts ).operator+= ( rights );
> }
>
> int main()
> {
> MyInt myi( 5 );
>
> // I am expecting error bu doesn't happen. Why?
> myi++ = 10;

You're assigning an integer to a temporary. The temporary will
go away as soon as the full expression is evaluated. It will be
destroyed with the value 10. Why would there be an error?

BTW, you stated that you "tried to overload the prefix ++ oprator"
while the class here has the *postfix* operator++ overloaded.

>
> cout << myi;
> }

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

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

== 1 of 2 ==
Date: Sun, Dec 28 2008 3:59 pm
From: Ichthyostega


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


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, ....?


Thanks
Hermann Vosseler

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

iD8DBQFJWBLhZbZrB6HelLIRAhvfAKDwT1b7f2sU0Mnfo6GhjCxWqUBA3QCgpzWq
Qiy/szkpY4lYukaqG7NqXPE=
=qzEq
-----END PGP SIGNATURE-----


== 2 of 2 ==
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


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

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: