Pretty Good Initialization Library

Just sent the message below to clc++m. Any comments are welcome. There's a library that I understand is being proposed for Boost: http://www.codeproject.com/vcpp/stl/PGIL.asp It does useful things, but it runs straight against the commonly given advice (with which I happen to agree) that one should not override operator, unless using expression templates that ensure left-to-right evaluation. So now, in the referenced article, the author makes the comment: " Overloading operator comma is sometimes viewed as a bad practice [3]. However, it has been done with success in eg. the Generative Matrix Computation Library and Blitz to initialize matrices (see [4]) and [5]). The Initialization Library overloads the comma operator in a safe manner by letting set_cont and set_map return an object that is responsible for the initialization. Therefore it takes explicit action from the programmer to begin using the overloaded operator,(). " I think the mentioned libraries do employ expression templates, while the initialization library does not. So I am unsatisfied. Anyone here can soothe my concerns? Is overloading the comma operator considered harmless after all? Andrei

Andrei Alexandrescu (See Website for Email) wrote:
Just sent the message below to clc++m. Any comments are welcome.
There's a library that I understand is being proposed for Boost:
Actually, it's even already accepted: see the first entry of "Past Review Results" in http://boost-consulting.com/boost/more/formal_review_schedule.html
It does useful things, but it runs straight against the commonly given advice (with which I happen to agree) that one should not override operator, unless using expression templates that ensure left-to-right evaluation.
So now, in the referenced article, the author makes the comment: " Overloading operator comma is sometimes viewed as a bad practice [3]. However, it has been done with success in eg. the Generative Matrix Computation Library and Blitz to initialize matrices (see [4]) and [5]). The Initialization Library overloads the comma operator in a safe manner by letting set_cont and set_map return an object that is responsible for the initialization. Therefore it takes explicit action from the programmer to begin using the overloaded operator,(). "
I think the mentioned libraries do employ expression templates, while the initialization library does not.
IIRC, Blitz has the following syntax to initialize an array A = 1, 2, 3; and I believe it's almost the same which this library does, and I *guess* the above does not involve expression templates -- just overloaded operator, which pushes data to the array.
So I am unsatisfied. Anyone here can soothe my concerns? Is overloading the comma operator considered harmless after all?
I think in this context it's more or less harmless. One can do: vector<int> v; v += 1, 2, 3; but the += operator is only defined for specific containers, and it's not defined for vector by default. So there's little risk that user will inadvertently use it, meaning something else. - Volodya

"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:ccg4pu$pns$1@sea.gmane.org...
I think in this context it's more or less harmless. One can do:
vector<int> v; v += 1, 2, 3;
but the += operator is only defined for specific containers, and it's not defined for vector by default. So there's little risk that user will inadvertently use it, meaning something else.
I was worried more (only) about the order of evaluation. If I understand correctly, if I call: v += foo(), bar(); the code will be same as: operator,(operator+=(v, foo()), bar()); so the order of executing foo() and bar() is unspecified. This might surprise the user. Andrei

"Andrei Alexandrescu \(See Website for Email\)" <andrewalex@hotmail.com> writes:
"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:ccg4pu$pns$1@sea.gmane.org...
I think in this context it's more or less harmless. One can do:
vector<int> v; v += 1, 2, 3;
but the += operator is only defined for specific containers, and it's not defined for vector by default. So there's little risk that user will inadvertently use it, meaning something else.
I was worried more (only) about the order of evaluation. If I understand correctly, if I call:
v += foo(), bar();
the code will be same as:
operator,(operator+=(v, foo()), bar());
so the order of executing foo() and bar() is unspecified. This might surprise the user.
Well, it might. But then, the user knows he's using the initialization library, and operator, has a different meaning in that context, just like operator<< means something else in the context of a Spirit gramar. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:u658z4xrh.fsf@boost-consulting.com...
Well, it might.
But then, the user knows he's using the initialization library, and operator, has a different meaning in that context, just like operator<< means something else in the context of a Spirit gramar.
I see. So I'd like to make a quick poll for Boosters: Overloading the comma operator in a way that could change order of evaluation of its arguments is: a) an obsolete coding standard b) a valid coding standard c) a valid coding standard, but for reasons x, y, and z, the initialization library doesn't violate it/violates it but gets away with it/etc. Thanks! Andrei

"Andrei Alexandrescu \(See Website for Email\)" <andrewalex@hotmail.com> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:u658z4xrh.fsf@boost-consulting.com...
Well, it might.
But then, the user knows he's using the initialization library, and operator, has a different meaning in that context, just like operator<< means something else in the context of a Spirit gramar.
I see. So I'd like to make a quick poll for Boosters: Overloading the comma operator in a way that could change order of evaluation of its arguments is:
a) an obsolete coding standard b) a valid coding standard c) a valid coding standard, but for reasons x, y, and z, the initialization library doesn't violate it/violates it but gets away with it/etc.
IMO it's only a valid coding standard if you also have a coding standard that says "operators must always act the same on user-defined types as they do on the builtins" -- which I would never accept ;-) Probably the right standard is: "If you're trying to define operators that act like the builtin ones, beware the overloading of operator,, operator&& and operator||, because you can't get identical semantics". But then, why would anyone want to overload operator, other than to change the semantics?? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:u7jtf3hxn.fsf@boost-consulting.com...
IMO it's only a valid coding standard if you also have a coding standard that says "operators must always act the same on user-defined types as they do on the builtins" -- which I would never accept ;-)
Probably the right standard is:
"If you're trying to define operators that act like the builtin ones, beware the overloading of operator,, operator&& and operator||, because you can't get identical semantics".
But then, why would anyone want to overload operator, other than to change the semantics??
That argument doesn't hold water. You do want to change the semantics, but not in ways that can be confusing or introduce subtle nonportabilities. Unlike all other overloadable operators, the three operators you mention have special regime in the way they evaluate their arguments, regime that cannot be emulated with regular function calls. That being said, I take it your answer was (a): it is an obsolete coding standard. Thanks. Any other votes and opinions are welcome. Andrei

"Andrei Alexandrescu \(See Website for Email\)" <andrewalex@hotmail.com> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:u7jtf3hxn.fsf@boost-consulting.com...
IMO it's only a valid coding standard if you also have a coding standard that says "operators must always act the same on user-defined types as they do on the builtins" -- which I would never accept ;-)
Probably the right standard is:
"If you're trying to define operators that act like the builtin ones, beware the overloading of operator,, operator&& and operator||, because you can't get identical semantics".
But then, why would anyone want to overload operator, other than to change the semantics??
That argument doesn't hold water. You do want to change the semantics, but not in ways that can be confusing or introduce subtle nonportabilities.
Can you think of one change to the semantics of operator, that _can't_ be confusing? Or any operator for that matter? And the "subtle nonportabilities" you're referring to are introduced by every expression whose order of evaluation is unspecified (of which every real program contains many). My point is that it's unlike any other operator: the built-in comma works on any type, even UDTs. So if you need sequencing, just use the built-in one. If you want it to do something else, go ahead and overload.
Unlike all other overloadable operators, the three operators you mention have special regime in the way they evaluate their arguments, regime that cannot be emulated with regular function calls.
That was what I meant by "you can't get identical semantics".
That being said, I take it your answer was (a): it is an obsolete coding standard.
I didn't give a straight answer because saying it's obsolete presumes it was once valid... and I don't see that anything has changed to make it more or less so.
Thanks. Any other votes and opinions are welcome.
I'll be silent now so someone else can reply. Ciao, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

But then, the user knows he's using the initialization library, and operator, has a different meaning in that context, just like operator<< means something else in the context of a Spirit gramar.
I see. So I'd like to make a quick poll for Boosters: Overloading the comma operator in a way that could change order of evaluation of its arguments is:
a) an obsolete coding standard b) a valid coding standard c) a valid coding standard, but for reasons x, y, and z, the initialization library doesn't violate it/violates it but gets away with it/etc.
I'm not sure which of a/b/c I am, but if I saw the below code I would be surprised if foo() was not evaluated before bar(). If it was a function: f( foo(), bar() ); would foo() always be executed before bar()? If I was reviewing that code I'd demand either a comment on that line pointing out that either could be called first, or request that foo() and bar() are evaluated and assigned to variables first. Darren
v += foo(), bar();
the code will be same as:
operator,(operator+=(v, foo()), bar());
so the order of executing foo() and bar() is unspecified. This might surprise the user.

In article <40EC84D1.5060604@dcook.org>, Darren Cook <darren@dcook.org> wrote:
I'm not sure which of a/b/c I am, but if I saw the below code I would be surprised if foo() was not evaluated before bar(). If it was a function: f( foo(), bar() ); would foo() always be executed before bar()?
No. This is a common misconception and a common source of bugs that only show up when optimizations are turned on. It's also a source of exception-unsafe code, as detailed in Exceptional C++ and a GOTW column. meeroh -- If this message helped you, consider buying an item from my wish list: <http://web.meeroh.org/wishlist>

I'm not sure which of a/b/c I am, but if I saw the below code I would be surprised if foo() was not evaluated before bar(). If it was a function: f( foo(), bar() ); would foo() always be executed before bar()?
No. This is a common misconception and a common source of bugs that only show up when optimizations are turned on. It's also a source of exception-unsafe code, as detailed in Exceptional C++ and a GOTW column.
That kind of validates using v+=foo(),bar(); then, but also says why you shouldn't use it: a common source of bugs. I think with an initialization library in particular people will write, and expect to always work, something like: v+= get(), get(), get(); Darren

"Darren Cook" <darren@dcook.org> wrote in message news:40EC9169.3060409@dcook.org...
I'm not sure which of a/b/c I am, but if I saw the below code I would be surprised if foo() was not evaluated before bar(). If it was a function: f( foo(), bar() ); would foo() always be executed before bar()?
No. This is a common misconception and a common source of bugs that only show up when optimizations are turned on. It's also a source of exception-unsafe code, as detailed in Exceptional C++ and a GOTW column.
That kind of validates using v+=foo(),bar(); then, but also says why you shouldn't use it: a common source of bugs.
I think with an initialization library in particular people will write, and expect to always work, something like: v+= get(), get(), get();
Were issues such as these brought during the review? Andrei

Darren Cook wrote:
No. This is a common misconception and a common source of bugs that only show up when optimizations are turned on. It's also a source of exception-unsafe code, as detailed in Exceptional C++ and a GOTW column.
That kind of validates using v+=foo(),bar(); then, but also says why you shouldn't use it: a common source of bugs.
I think with an initialization library in particular people will write, and expect to always work, something like: v+= get(), get(), get();
They surely will expect this to work and it might fail if 'get()' result depend on the call order. In fact *any* convenient initialization syntax will have this problem just becase you'd have single expression, and the order of evaluation is not specified. So, the question is whether use of "," above makes user think that the order of evaluation is specified? I think it does not matter. Most users don't know about sequence points and operator,. The mostly use operator,() inside header of 'for' loop and don't think much about it. They will have specific evaluation order in mind for any syntax, for example: desc.add_options() ( get() ) ( get() ) ; So, the primary thing is avoiding unsafe 'get()'s functions, like one which modify global state or return naked pointers. - Volodya

"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:200407081142.06605.ghost@cs.msu.su...
Darren Cook wrote:
No. This is a common misconception and a common source of bugs that only show up when optimizations are turned on. It's also a source of exception-unsafe code, as detailed in Exceptional C++ and a GOTW
column. > > > > That kind of validates using v+=foo(),bar(); then, but also says why you > > shouldn't use it: a common source of bugs. > > > > I think with an initialization library in particular people will write, and > > expect to always work, something like: > > v+= get(), get(), get(); > > They surely will expect this to work and it might fail if 'get()' result > depend on the call order. In fact *any* convenient initialization syntax will > have this problem just becase you'd have single expression, and the order of > evaluation is not specified.
So, the question is whether use of "," above makes user think that the order of evaluation is specified? I think it does not matter. Most users don't know about sequence points and operator,. The mostly use operator,() inside
I think Darren was referring to get() as of a read() function that bumps some stream pointer. At any rate, I believe your comment is inaccurate. The classic array initialization { expr, expr, expr ... } does not have that problem, and is convenient. header
of 'for' loop and don't think much about it.
"Nobody knows what most programmers do" -- Bjarne Stroustrup :o) (The emoticon is mine.) Unfortunately, the discussion does not flow the way I had hoped :o). My intent is to figure out the opinion of the boost community about the advice against overloading the comma, and, and or operators, given by people like Scott Meyers and others. Is that a good coding standard or not? Andrei

From: "Andrei Alexandrescu \(See Website for Email\)" <andrewalex@hotmail.com>
Unfortunately, the discussion does not flow the way I had hoped :o). My intent is to figure out the opinion of the boost community about the advice against overloading the comma, and, and or operators, given by people like Scott Meyers and others. Is that a good coding standard or not?
It's certainly not to be done without understanding the ramifications. Clearly, the average user doesn't know anything about sequence points and those of us aware of them don't always remember all of the rules. Thus, it can be dangerous to overload operator, and thus a coding guideline that warns against it is warranted. (A separate issue is whether it is the appropriate operator for the initialization library regardless of its prior acceptance into Boost.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
Unfortunately, the discussion does not flow the way I had hoped :o). My intent is to figure out the opinion of the boost community about the advice against overloading the comma, and, and or operators, given by people like Scott Meyers and others. Is that a good coding standard or not?
It's certainly not to be done without understanding the ramifications. Clearly, the average user doesn't know anything about sequence points and those of us aware of them don't always remember all of the rules. Thus, it can be dangerous to overload operator, and thus a coding guideline that warns against it is warranted.
But the same user will be equally unprepared to unspecified evaluation order in A = get(), get(), get(); and in A.assign_list(get())(get())(get()) ; There's nothing specific about operator,(); - Volodya

It's certainly not to be done without understanding the ramifications. ...
But the same user will be equally unprepared to unspecified evaluation order in
A = get(), get(), get();
and in
A.assign_list(get())(get())(get()) ;
There's nothing specific about operator,();
Wouldn't A << get() << get() << get() ; always work the way the user expects, even when they switch all optimizations on? So wouldn't it be better for the initialization library to use operator<< instead of operator, ? (not sure if that is possible or not - I've not looked at that library). In answer to Andrei's original question I think b) not overloading operator,() is still a valid coding standard, because I personally don't know - and do not want to have to know - what a "sequence point" is. Darren

Darren Cook wrote:
It's certainly not to be done without understanding the ramifications. ...
But the same user will be equally unprepared to unspecified evaluation order in
A = get(), get(), get();
and in
A.assign_list(get())(get())(get()) ;
There's nothing specific about operator,();
Wouldn't A << get() << get() << get() ;
always work the way the user expects,
I think user will still expect specific evaluation order above. And from standard point of view, it does not have more sequence points than either of the other versions. Finally, this still looks like formatted insertion to me.
even when they switch all optimizations on?
It's almost impossible (IMO) for compiler to get the unexpected evaluation order in either case. For agruments of one function call, compiler will likely to evaluate arguments either staring from the first one, or from the last one, depending on the calling conversion. But for: operator()(get()).operator()(get()).operator()(get()) (or for comma), it's very unlikely that compiler will start by evaluating all 'get()' calls and then proceed by calling operator(). It's a strange logic to implement, and would require you too keep all results from 'get()' somewhere, increasing register pressure. So maybe, it's mostly theoretic issue. - Volodya

"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:200407091141.40483.ghost@cs.msu.su...
But the same user will be equally unprepared to unspecified evaluation order in
A = get(), get(), get();
and in
A.assign_list(get())(get())(get()) ;
There's nothing specific about operator,();
There is, sigh. operator,() has a special regime among operators. It's called the /sequencing/ operator. It does that, /sequencing/, like a champ. Pretty much nothing else. Other operators don't specify the order of evaluation. This one (and && and ||) does. When overloading it, that important property of operator,() is lost. Andrei

Andrei Alexandrescu (See Website for Email) wrote:
But the same user will be equally unprepared to unspecified evaluation ....... in
A = get(), get(), get();
and in
A.assign_list(get())(get())(get()) ;
There's nothing specific about operator,();
There is, sigh. operator,() has a special regime among operators. It's called the /sequencing/ operator.
Uhm :-( It seems you did not read the part of my email which said *the same user*. The user which does not care about possibly different initialization order probably does not care about special properties of operator,(). As Andras Erdei the gap between people who know about special properties of operator(), and those who know that overloaded version does not have that properties is very, very narrow. - Volodya

"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:200407100957.39472.ghost@cs.msu.su...
Andrei Alexandrescu (See Website for Email) wrote:
But the same user will be equally unprepared to unspecified evaluation ....... in
A = get(), get(), get();
and in
A.assign_list(get())(get())(get()) ;
There's nothing specific about operator,();
There is, sigh. operator,() has a special regime among operators. It's called the /sequencing/ operator.
Uhm :-( It seems you did not read the part of my email which said *the same user*. The user which does not care about possibly different initialization order probably does not care about special properties of operator,().
I have had. No change in my answer. :o)
As Andras Erdei the gap between people who know about special properties of operator(), and those who know that overloaded version does not have that properties is very, very narrow.
Let's not forget that this basis is just a conjecture. Andrei

Andrei Alexandrescu (See Website for Email) wrote:
As Andras Erdei the gap between people who know about special properties
of
operator(), and those who know that overloaded version does not have that properties is very, very narrow.
Let's not forget that this basis is just a conjecture.
The opposite statement, that user expects operator, to do sequencing and will expect the same from overloaded one, is conjecture as well. I think it's a bit hard to draw any definitive conclusion that overloading operator, is evil unless users of assignment library will start complaining here, and I don't thin I have more to add. - Volodya

Andrei Alexandrescu (See Website for Email) wrote:
As Andras Erdei the gap between people who know about special
of
operator(), and those who know that overloaded version does not have
"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:200407101115.35218.ghost@cs.msu.su... properties that
properties is very, very narrow.
Let's not forget that this basis is just a conjecture.
The opposite statement, that user expects operator, to do sequencing and will expect the same from overloaded one, is conjecture as well.
That is very very true indeed.
I think it's a bit hard to draw any definitive conclusion that overloading operator, is evil unless users of assignment library will start complaining here, and I don't thin I have more to add.
Great. No need to get irritated; in some sense, we're all in the same boat. :o) For the record, I've decided to eliminate that coding standard for now. The sheer facts that (1) a useful library overloading operator,() is in boost, and (2) reasonable people can disagree about said overloading being good or bad, convinced me. Andrei

Andrei Alexandrescu (See Website for Email) wrote:
Let's not forget that this basis is just a conjecture.
The opposite statement, that user expects operator, to do sequencing and
will
expect the same from overloaded one, is conjecture as well.
That is very very true indeed.
In fact, there's a general problem with all coding guidelines. One person was burned (or believes it's easy to get burned) by a something, so he finds that something dangerous. Other person was not burned, so he thinks otherwise. And if no real evidence exists, arguments can become too abstract. It would be great to have some site, where folks could list designs or low-level idioms which lead to bugs. That would gather needed evidence. I used to have such list for myself, so, for example, I'll never write for(size_t i = ..., i >= 0; --i) any more ;-) Of course, creating such global list is very hard.
I think it's a bit hard to draw any definitive conclusion that overloading operator, is evil unless users of assignment library will start
complaining
here, and I don't thin I have more to add.
Great. No need to get irritated; in some sense, we're all in the same boat.
:o)
True. I don't think I was irritated at all -- just run out of arguments. This was sure a good discussion! - Volodya

In fact, there's a general problem with all coding guidelines. One person was burned (or believes it's easy to get burned) by a something, so he finds
"Vladimir Prus" <ghost@cs.msu.su> wrote in message news:200407121609.36583.ghost@cs.msu.su... that
something dangerous. Other person was not burned, so he thinks otherwise. And if no real evidence exists, arguments can become too abstract.
How do they say... all generalizations are false? :o) I disagree. There are coding guidelines that are generally accepted within reason and when the forces are properly explained. For example, virtual functions are preferable to switching on type, for objective reasons (modularity, extensibility, flexibility). Now there are cases when that guideline won't apply, so as long as those cases are identified and spelled out, I think that is a fair coding guideline on which most reasonable people would agree.
It would be great to have some site, where folks could list designs or low-level idioms which lead to bugs. That would gather needed evidence. I used to have such list for myself, so, for example, I'll never write
for(size_t i = ..., i >= 0; --i)
any more ;-) Of course, creating such global list is very hard.
In fact, here's a little guideline that everybody would agree with. :o) Andrei

On 7/10/04 12:32 PM, "Andrei Alexandrescu (See Website for Email)" <andrewalex@hotmail.com> wrote:
For the record, I've decided to eliminate that coding standard
on overloading operator,()
for now. The sheer facts that (1) a useful library overloading operator,() is in boost, and (2) reasonable people can disagree about said overloading being good or bad, convinced me.
I'm disappointed in this. While there may be identifiable exception cases, I think in general overloading operator,() is problematic. I think the initialization library's use of the comma operator in this way is like the streams use of >> and <<. These are really new operators which happen to be spelled the same way as old operators. When we see "std::cout << ...", we don't think, "Oh, this is bit shift which in the case of streams means..." No we think "Oh, this is the insertion operator..." I think of the comma operator as the sequence operator and as such it cannot be properly overloaded. To overload operator,() in the way that the initialization library does is to introduce a new operator in much the same way that the stream class did with << and >>. Perhaps the coding guideline should be "overload operator,() only when you wish to create a new semantic meaning for the comma operator (other than sequence) and see the coding guideline that says to avoid creating new semantic meanings for operators." -- Jon Kalb

Hi, I am having problem when running the following c++ code. The system tells me "Unhandled exception ....": (I also tried running PyRun_String with the string identical to strings in hello.py, and it worked fine.) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <boost/python.hpp> #include <iostream> using namespace boost::python; int main () { Py_Initialize (); object main_module (handle<> (borrowed (PyImport_AddModule("__main__")))); object main_namespace = main_module.attr ("__dict__"); std::string filename = "hello.py"; FILE *fp = fopen( filename.c_str(), "r" ); if (fp == NULL) { std::cerr << "failed to open file" << std::endl; return -1; } handle<> (PyRun_File ( fp , const_cast<char*>(filename.c_str()) , Py_file_input , main_namespace.ptr() , main_namespace.ptr())); fclose(fp); Py_Finalize (); return 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// (Here is the content of hello.py:) #################### hello = file('hello.txt', 'w') hello.write('Hello world!') hello.close() #################### Can anyone point me what do I need to get it running. Thanks very much! Regards, Gao Yang

Gao Yang <gaoyang@gmail.com> writes:
Hi,
I am having problem when running the following c++ code. The system tells me "Unhandled exception ....":
(I also tried running PyRun_String with the string identical to strings in hello.py, and it worked fine.)
1. Please bring future Boost.Python questions to the appropriate mailing list: http://www.boost.org/more/mailing_lists.htm#cplussig 2. You can't use PyFinalize with Boost.Python (http://www.boost.org/libs/python/todo.html#pyfinalize-safety) 3. Wrap your PyRun_String in handle_exception as shown in http://www.boost.org/libs/python/test/embedding.cpp HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

There is, sigh. operator,() has a special regime among operators. It's called the /sequencing/ operator. It does that, /sequencing/, like a champ. Pretty much nothing else. Other operators don't specify the order of evaluation. This one (and && and ||) does. When overloading it, that important property of operator,() is lost.
Hi Andrei, Sorry for the late reply...computer time is scarce during holidays :-) Let me first say that I agree that my documentation should state that one cannot rely on the evaluation order of expressions in the comma-list, just like in normal functions. If all goes as it should, the user will never handle objects that overload operator, directly. So it shouldn't affect your normal use of operator, at all. btw, the library is now called boost.assign and can already be found in the main cvs under boost/assign and libs/assign The docs are almost done. br Thorsten

From: Vladimir Prus <ghost@cs.msu.su>
Rob Stewart wrote:
It's certainly not to be done without understanding the ramifications. Clearly, the average user doesn't know anything about sequence points and those of us aware of them don't always remember all of the rules. Thus, it can be dangerous to overload operator, and thus a coding guideline that warns against it is warranted.
But the same user will be equally unprepared to unspecified evaluation order in
A = get(), get(), get();
and in
A.assign_list(get())(get())(get()) ;
There's nothing specific about operator,();
Ah, but the user that would be confused by those things is also far less likely to do them. The initialization library brings to the fore a dark corner of the language of which most programmers are unware. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Quoting "Andrei Alexandrescu (See Website for Email)" <andrewalex@hotmail.com>:
Unfortunately, the discussion does not flow the way I had hoped :o). My intent is to figure out the opinion of the boost community about the advice against overloading the comma, and, and or operators, given by people like Scott Meyers and others. Is that a good coding standard or not?
Another question I find equally, if not more interesting is: did anybody here run into any real problems due to the comma operator being overloaded in this way? I haven't, but I never used libraries like Blitz++ in any big projects. Although most of Scott Meyers' advice is very reasonable, I sometimes find that his books lack references to real projects where the problems he mentions surfaced. Is it educated guesses or real experience? Here's a wager: The majority of C++ programmers are not aware that the evaluation order of function arguments is implementation-defined. Now if this is true, and they get along OK anyway, couldn't they also get along with the quirky evaluation rules for the comma operator? My answer to your poll would be d) Not always an invalid coding standard, and in the case of the initialization library it is valid until proven otherwise. /Mattias

Andrei Alexandrescu (See Website for Email) wrote:
expect to always work, something like: v+= get(), get(), get();
They surely will expect this to work and it might fail if 'get()' result depend on the call order. In fact *any* convenient initialization syntax
will
have this problem just becase you'd have single expression, and the order
of
evaluation is not specified.
I think Darren was referring to get() as of a read() function that bumps some stream pointer.
Yes, I don't think I contradict to that.
At any rate, I believe your comment is inaccurate. The classic array initialization { expr, expr, expr ... } does not have that problem, and is convenient.
Ehm, since we're talking about assignment library, then I surely mean any intialization syntax *except for classic one*. If we agree the classic one is OK, then we don't have a problem to solve.
of 'for' loop and don't think much about it.
"Nobody knows what most programmers do" -- Bjarne Stroustrup :o)
(The emoticon is mine.)
I know about folks which are phisically around me -- they don't know what sequence point it.
Unfortunately, the discussion does not flow the way I had hoped :o). My intent is to figure out the opinion of the boost community about the advice against overloading the comma, and, and or operators, given by people like Scott Meyers and others. Is that a good coding standard or not?
Ok, then my answer to your question is: - (c), in case everybody knows about sequence points, immediately aware of unspecified evaluation order everywhere, and use comma to force specific evaluation order. - (a), otherwise - Volodya

On 7/7/04 12:08 PM, "Andrei Alexandrescu (See Website for Email)" <andrewalex@hotmail.com> wrote:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:u658z4xrh.fsf@boost-consulting.com...
Well, it might.
But then, the user knows he's using the initialization library, and operator, has a different meaning in that context, just like operator<< means something else in the context of a Spirit gramar.
I see. So I'd like to make a quick poll for Boosters: Overloading the comma operator in a way that could change order of evaluation of its arguments is:
a) an obsolete coding standard b) a valid coding standard c) a valid coding standard, but for reasons x, y, and z, the initialization library doesn't violate it/violates it but gets away with it/etc.
I don't understand what the extra descriptions in [c] mean. How does [c] differ from [b]? Also, the initial question is badly formed. It implies that there is a method of overloading the comma operator _without_ making argument evaluation order arbitrary. There isn't. (It's either using the built-in operator in list order, or an user-defined version in arbitrary order.) -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

"Daryle Walker" <darylew@hotmail.com> wrote in message news:BD1483E4.C2DD%darylew@hotmail.com...
On 7/7/04 12:08 PM, "Andrei Alexandrescu (See Website for Email)" <andrewalex@hotmail.com> wrote:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:u658z4xrh.fsf@boost-consulting.com...
Well, it might.
But then, the user knows he's using the initialization library, and operator, has a different meaning in that context, just like operator<< means something else in the context of a Spirit gramar.
I see. So I'd like to make a quick poll for Boosters: Overloading the comma operator in a way that could change order of evaluation of its arguments is:
a) an obsolete coding standard b) a valid coding standard c) a valid coding standard, but for reasons x, y, and z, the initialization library doesn't violate it/violates it but gets away with it/etc.
I don't understand what the extra descriptions in [c] mean. How does [c] differ from [b]?
[b] implies that the initialization library is in violation of that coding standard. [c] implies that the initialization library has reasons that makes it exempt from that coding standard.
Also, the initial question is badly formed. It implies that there is a method of overloading the comma operator _without_ making argument evaluation order arbitrary. There isn't. (It's either using the built-in operator in list order, or an user-defined version in arbitrary order.)
There is: expression templates. Andrei

On 7/9/04 5:40 PM, "Andrei Alexandrescu (See Website for Email)" <andrewalex@hotmail.com> wrote:
"Daryle Walker" <darylew@hotmail.com> wrote in message news:BD1483E4.C2DD%darylew@hotmail.com...
On 7/7/04 12:08 PM, "Andrei Alexandrescu (See Website for Email)" <andrewalex@hotmail.com> wrote: [SNIP]
I see. So I'd like to make a quick poll for Boosters: Overloading the comma operator in a way that could change order of evaluation of its arguments is:
a) an obsolete coding standard b) a valid coding standard c) a valid coding standard, but for reasons x, y, and z, the initialization library doesn't violate it/violates it but gets away with it/etc.
I don't understand what the extra descriptions in [c] mean. How does [c] differ from [b]?
[b] implies that the initialization library is in violation of that coding standard. [c] implies that the initialization library has reasons that makes it exempt from that coding standard.
Also, the initial question is badly formed. It implies that there is a method of overloading the comma operator _without_ making argument evaluation order arbitrary. There isn't. (It's either using the built-in operator in list order, or an user-defined version in arbitrary order.)
There is: expression templates.
How can expression templates re-instate evaluation order? (Note: I'm a newbie at expression templates.) -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com
participants (11)
-
Andrei Alexandrescu (See Website for Email)
-
Darren Cook
-
Daryle Walker
-
David Abrahams
-
Gao Yang
-
Jon Kalb
-
Mattias Flodin
-
Miro Jurisic
-
Rob Stewart
-
Thorsten Ottosen
-
Vladimir Prus