Associativity and Commas - a plea for help!
Author |
Message |
pallex.. #1 / 18
|
 Associativity and Commas - a plea for help!
(Sorry if this has been sent twice, but i`m using dejanews.com, which sucks hard.) Hi! I`m a fairly strong C programmer, but i have a few queries that i`m sure someone here can help me with. I`m really after short explanations, a ptr to an on-line tutorial or book that will explain. 1) The comma operator. I dont have any C books in front of me, but aren`t comma operators used to specify the execution order of a series of steps (expressions?). I`ve used : ... for (i=0,j=28;i<100;i++) ... but only in for loops. Does it have any other uses? ( I dont mean seperating parameters to functions, initialising arrays etc, i mean specifically in specifying order of execution. I dont see any examples that i understand. Can you use commas to solve problems like : i = j + j++ + j; where the compiler is free to evaluate the expression however it wishes? 2) Left/right associativity. I sort of understand why : a = *p++; is taken to mean a = *p; p++; But why isnt the * operator higher? Basically, i`m unsure of the `interaction` between precedence and associativity. How can i guarantee that my brain can work through examples of this on paper in the same way the compiler works it out. I`ve not yet read a good definition of associativity. Does anyone have any tricks or methods they want to share? Or is it really simple and i`m missing the point and over-complicating it all? Hopefully someone out there has been there and knows what i`m talking about, and can help. I seem to be well beyond beginners level, but some of the stuff i see when i browse these groups or read `C/C++ Journal` and `Dr Dobbs` looks scary too! Regards, Alex. (pallex at rocketmail dot com) Sent via Deja.com http://www.*-*-*.com/ Share what you know. Learn what you don't. --
|
Sun, 10 Feb 2002 03:00:00 GMT |
|
 |
Sunil Ra #2 / 18
|
 Associativity and Commas - a plea for help!
[To the moderator: I'm mailing you this directly because my newsserver has been misconfigured and appears not to be letting me post directly to moderated groups. Thanks -sunil] Quote:
> 1) The comma operator. I dont have any C books in front of me, but > aren`t comma operators used to specify the execution order of a series > of steps (expressions?). I`ve used : > ... > for (i=0,j=28;i<100;i++) > ... > but only in for loops. Does it have any other uses? ( I dont mean > seperating parameters to functions, initialising arrays etc, i mean > specifically in specifying order of execution. I dont see any examples > that i understand. Can you use commas to solve problems like :
Yes, you can certainly use the comma operator for things other than for loops. The comma is a sequence point, which basically means that any side-effects are guaranteed to be complete by then you "move past" the comma operator. The C FAQ has examples of what is perhaps the most common use of this operator (function-like macros). Quote: > i = j + j++ + j; > where the compiler is free to evaluate the expression however it wishes?
The compiler has even more freedom than that, it can do whatever it likes with that expression. Essentially, as per the C standard what happens here is "undefined behaviour". IOW, anything could happen. Again, the C FAQ deals with this in greater depth. Quote: > 2) Left/right associativity. I sort of understand why : > a = *p++; > is taken to mean > a = *p; > p++;
It actually means a = *(p++); The ++ operator takes precedence over the * operator. If you want to increment the value actually pointed to instead, you should do a = (*p)++; This is a precedence issue, it has nothing to do with associativity. Associativity comes about primarily when you have an instance of two adjacent operators having the same precedence. Quote: > But why isnt the * operator higher?
It's the way the language was originally designed. Seriously, it's more "useful" to have the precdence levels this way - it just crops up more often in code. C isn't Lisp. :) Quote: > Basically, i`m unsure of the > `interaction` between precedence and associativity. > How can i guarantee that my brain can work through examples of this on > paper in the same way the compiler works it out.
Every good textbook or reference manual will have a precedence table in it. Some common ones, like this one, are worth committing to memory via constant use. Just write a few small example test programs and make sure you fully understand what's going on. Quote: > I`ve not yet read a > good definition of associativity. Does anyone have any tricks or > methods they want to share? Or is it really simple and i`m missing the > point and over-complicating it all?
It might be worth your taking a look at "C - A Reference Manual", 4th Edn, Samuel P Harbison and Guy L Steele Jr. A lot of this sort of stuff is fully explained in there. -- { Sunil Rao } "...certainly no beast has essayed the boundless, infinitely inventive art of human hatred. No beast can match its range and power." - Arundhati Roy, "The God of Small Things", 1997. --
|
Sun, 10 Feb 2002 03:00:00 GMT |
|
 |
Francis Glassboro #3 / 18
|
 Associativity and Commas - a plea for help!
writes Quote: >Hi! >I`m a fairly strong C programmer, but i have a few queries that i`m >sure someone here can help me with. I`m really after >short explanations, a ptr to an on-line tutorial or book that will >explain. >1) The comma operator. I dont have any C books in front of me, but >aren`t comma operators used to specify the execution order of a series >of steps (expressions?). I`ve used :
One problem here is that a comma is both an operator and a punctuator depending on context. Most of the uses are punctuators, i.e. simply separating out several items (such as the elements of an argument list). In this context it has nothing to say about the order of evaluation. Within an expression it is a sequence operator and requires completion of all the side effects of evaluating the left operand before evaluation of the right operand. It actually has relatively little use because virtually every use can be replaced by writing distinct statements separated by semicolons. The place I use it is where I want to express that something is conceptually one action even though it may require evaluation of two expressions sequentially. E.g.: int * ptr = malloc(somestorage); /* code */ free(ptr), ptr = 0; /* release the memory and place the pointer in a safe state. */ Quote: Not really. In such cases you need to write what you mean. Even without the undefined behaviour of writing to storage that is being read for another purpose, such lines have problems with order of evaluation which are not going to be resolvable with sequence operators. Quote: >where the compiler is free to evaluate the expression however it wishes?
Or anything else it elects to do because you read (evaluate) j for purposes other than writing to it. Quote: >2) Left/right associativity. I sort of understand why : >a = *p++; >is taken to mean >a = *p; >p++;
You are confusing associativity which in the computing context refers to the order in which multiple successive operators of the same class are evaluated, with precedence that determines the order in which different operators are evaluated. Note that it is subexpressions that are subject to no defined order of evaluation though there are rules about ordering of evaluation of operators (confusing? yes but the only way to clarify that confusion is by working at it) Quote: >But why isnt the * operator higher? Basically, i`m unsure of the >`interaction` between precedence and associativity. >How can i guarantee that my brain can work through examples of this on >paper in the same way the compiler works it out. I`ve not yet read a >good definition of associativity. Does anyone have any tricks or >methods they want to share? Or is it really simple and i`m missing the >point and over-complicating it all?
Look: a=b=c=0; zeroes a, b and c because assignment associates right to left. If it worked left to right a would take the value of b, b that of c and c would become zero. double a=1.0, b=2.0, c=3.0; a = a/b/c; is required to evaluate a divided by b and then divide the result by c. a = a/b*c; is required to evaluate (a divided by b) times c Both these are because multiplicative operators (that includes division) associate left to right. a = a+ b/c; requires that b is divided by c and the result is added to a because additive operators (also associating left to right) have lower precedence than multiplicative ones. and all the above work because assignment has a lower precedence than arithmetic operators. Quote: >Hopefully someone out there has been there and knows what i`m talking >about, and can help. I seem to be well beyond beginners level, but some >of the stuff i see when i browse these groups or read `C/C++ Journal` >and `Dr Dobbs` looks scary too!
Well perhaps you should class your self as an experienced novice:) At least you know enough to ask. Francis Glassborow Journal Editor, Association of C & C++ Users 64 Southfield Rd Oxford OX4 1PA +44(0)1865 246490 All opinions are mine and do not represent those of any organisation --
|
Sun, 10 Feb 2002 03:00:00 GMT |
|
 |
Oleg Goldshmid #4 / 18
|
 Associativity and Commas - a plea for help!
It seems to me that both your questions indicate that you would like to be clever in your programming, and use the facilities of the language to the limit. If that is the case (and maybe it isn't), be warned that it is a bad idea. Don't write clever code, write clear one. I will address that for both questions of yours. Quote:
> 1) The comma operator. I dont have any C books in front of me, but > aren`t comma operators used to specify the execution order of a series > of steps (expressions?). I`ve used : > ... > for (i=0,j=28;i<100;i++) > ... > but only in for loops. Does it have any other uses?
Yes, most often to write multi-statement macros, ONLY in the cases where all the statements are simple exressions, not declarations or loops. You can write a parenthesized expression separating sub-statements with commas, and even "return a value" from a macro. See the comp.lang.c FAQ, #10.4, #10.26. Usually, even this is not such a great idea (to quote Kernighan and Pike from memory, "the C preprocessor is a blunt tool"). FAQ #10.26 gives an example and discusses the disadvantages. Another possible use for comma is when the order of operations is very clear, such as in the swap (UNTESTED): void swap(int *x, int *y) { int tmp; tmp = *x, *x = *y, *y = *x; Quote: }
I personally don't see any advantage in this over 3 separate statements. Quote: > ( I dont mean seperating parameters to functions, initialising > arrays etc, i mean specifically in specifying order of execution.
Those commas are not comma operators, and do not guarantee left to right evaluation. Quote: > I dont see any examples > that i understand. Can you use commas to solve problems like : > i = j + j++ + j; > where the compiler is free to evaluate the expression however it > wishes?
Do you mean i = j, i += j, j++, i += j; Even though you can, there is no need to do that. Just write separate statements - the code will be easier to read, understand, and maintain. Quote: > 2) Left/right associativity. I sort of understand why : > a = *p++; > is taken to mean > a = *p; > p++;
Or a = *p, p++; ;-) Quote: > But why isnt the * operator higher?
Indirection (*) is at the same level of precedence as the increment and decrement operators. Why? I can venture a guess regarding this particular case: it is such a common thing to increment a pointer... Quote: > Basically, i`m unsure of the `interaction` between precedence and > associativity.
When precedence is the same, the associativity rules are used. Quote: > How can i guarantee that my brain can work through examples of this on > paper in the same way the compiler works it out.
There are two bad ways, a very bad way, and a good way. The good way is to always use parentheses to remove any ambiguity. This doesn't help when you have to read code which doesn't use parentheses (I hate that). Then you are stuck with the bad ways. The very bad way is to remember all the precedence and associativity rules. The bad way that I use is to consult a reference. I do that because I don't think it is worth my while to use the other bad way, which is to remember that: 1) all binary operators except assignments are left-associative; 2) assignments and the ternary conditional are right-associative; 3) the unary and postfix operators are right-associative. The last rule merely says that *p++ is *(p++) and not (*p)++. Harbison & Steele suggest remembering that the postfix operators have higher precedence than the prefix unary operators. And once again, don't abuse either the comma operator or the precedence rules. There is nothing wrong with using separate statements, or with putting parentheses wherever they remove any doubt about the order of evaluation. Don't be clever. --
"Life's not fair, but the root password helps." [S.Travaglia] --
|
Sun, 10 Feb 2002 03:00:00 GMT |
|
 |
Chris Tore #5 / 18
|
 Associativity and Commas - a plea for help!
writes, in part: Quote: >2) Left/right associativity. ... Basically, i`m unsure of the >`interaction` between precedence and associativity.
It might help to keep in mind that the C language as defined by the C standard has neither precedence nor associativity. The trick here is that C expressions are "parsed" according to a "grammar". Consider an expression like: a * b + c * d This might be grouped the same as any of: ((a * b) + c) * d /* we do not want this one */ a * (b + (c * d)) /* nor this one */ (a * (b + c)) * d /* nor this one */ or various other possibilities; but we *want* it to come out as: (a * b) + (c * d) /* this is the one we really want */ The question then is, how do we arrange for a compiler to do this? The C standard uses a "fully factored" grammar. One small and highly simplified subset of this grammar is: mulexp: identifier mulexp * identifier expression: mulexp expression + mulexp Now, using this grammar, your job is to see how: a * b + c * d could possibly be an "expression". Note that a, b, c, and d are "identifiers". So for the whole line above to be an "expression", it had better begin with a mulexp, possibly followed by a "+" and then another mulexp. Is there a mulexp there, possibly followed by a "+"? Well, "a" is an identifier, and a mulexp can be an identifier. There is something after "a", and it is not a "+", but rather a "*", so it fits the first two parts of "mulexp * identifier". Is the thing after the "*" an identifier? It is "b", so yes. That means "a * b" is a mulexp. The next thing is a "+", which cannot be part of a "mulexp" -- only identifiers and "*"s can go into "mulexp"s. So we have completed matching one "mulexp". Now there is still a "+", so we can try the "expression + mulexp" line, having matched the first "expression" against "mulexp". That means whatever comes after the "+" had better be another "mulexp". Is it? By the same reasoning as for "a * b" above, "c * d" is a valid mulexp. That means "a * b" is a mulexp, which is an expression (by the first rule -- "expression: mulexp"), and "c * d" is a mulexp, and the whole thing is an "expression" by the "expression + mulexp" rule. In order to get here, we were forced to "bind up" the "a * b" as a single unit, and then "bind up" the "c * d", and only then "bind up" the "expression + mulexp". That means that to compute the value of the whole thing, we will have to add "a * b" and "c * d", not do something like "a * (b + c) * d". The C Standard's grammar achieves the desired grouping without using either precedence or associativity. There is simply no other way to turn "a * b + c * d" into an "expression". If you try to group the "b + c" first, the "a *" and "* d" will not match the grammar rules, so you would have a syntax error. Quote: >How can i guarantee that my brain can work through examples of this on >paper in the same way the compiler works it out.
This is where precedence and associativity come in. If you read the actual C Standard's grammar, you will see that I left out a lot of detail. An "expression" is actually an "assignment-expression" which goes through things like "conditional-expression" and "logical-OR-expression" and so on long before it gets to addition and multiplication; after that it goes on through things like "cast-expression" and "unary-expression" and "postfix-expression" before it ever gets to "identifier". It is far easier to remember that, given: a * b + c * d the multiplication has "higher precedence". We all had some form of "My Dear Aunt Sally" (Multiplication and Division, then Addition and Subtraction) drummed into us in primary school. We all know to group this as "a * b", then "c * d", then "+", because we have been doing it for years. Precedence works for more than just */ and +-, and we can write an equivalent grammar using precedence rules to make sure we get the right grouping. This is easier to *remember*. Precedence, however, only handles things like "a * b + c * d". What about "a / b / c"? This could be either: (a / b) / c, or a / (b / c). The results will be different. So we need one more grouping rule, and that one is "associativity". Things that are left-associative, we group (by mentally adding parentheses) on the left: a / b / c is left-associative, so it "means": (a / b) / c Things that are right-associative, we group on the right: w = x = y "means" w = (x = y) Like precedence, we fall back on associativity only when there are two or more ways to read something. Until then -- such as, if precedence tells us to read something only one way -- we can ignore it. The pitfall in "thinking about" expressions in terms of precedence and associativity is that it leads people to think that, if the expression has to *group* that way, it has to *evaluate in that order*. This is not true in C. The best illustrations occur when using functions that print messages when they are called: x = a() * b() + c() * d(); Suppose a(), b(), c(), and d() all print "in a", "in b", etc., when they are called. Using either the Standard C grammar, or a simpler-for-people grammar with precedence and associativity rules, we know that this has to be *grouped as*: - collect up a() and b(), and multiply - collect up c() and d(), and multiply - add but the compiler could implement this by calling c() first, then a(), then b(), then d() -- or any other order -- as long as it produces the same final number to put into "x". Thus, precedence and associativity exist only in our heads, not in the Standard C language; and they do not determine evaluation order. -- In-Real-Life: Chris Torek, Berkeley Software Design Inc
--
|
Mon, 11 Feb 2002 03:00:00 GMT |
|
 |
Mark Brad #6 / 18
|
 Associativity and Commas - a plea for help!
In a superb article, Chris Torek writes: Quote: > Precedence, however, only handles things like "a * b + c * d". > What about "a / b / c"? This could be either: (a / b) / c, or > a / (b / c). The results will be different. So we need one more > grouping rule, and that one is "associativity". > Things that are left-associative, we group (by mentally adding > parentheses) on the left: > a / b / c > is left-associative, so it "means": > (a / b) / c > Things that are right-associative, we group on the right: > w = x = y > "means" > w = (x = y)
There are two more things to be said here. The first is that the standard does not specify associativity directly, any more than it does precedence. Rather, the grammar of expressions is written in such a way as to determine the associativity. Note the assymetric grammatical rule in the simplified grammar that Chris provided: expression: mulexp expression + mulexp This makes + left-associative. If the last line was "mulexp + expression", + would be right-associative. The second thing is a reminder that this now common usage of "associa- tivity" is completely at variance with the mathematical meaning of the term, making another possible source of confusion. If it matters whether something is "left-associative" or "right-associative", then to a mathematician, it is *not* associative, or to put it another way, *does not have* associativity. If an operator *is* associative in the mathematical sense, this means that both groupings are guaranteed to produce equivalent results. C operators that are in fact associative in the mathematical sense include the comma operator (,) and the logical operators (&& and ||). The C grammar makes each one left- or right-associative, but in the cases of these operators the result of the expression would be the same if the opposite choice had been made in the grammar. That is, x&&y&&z is required to parse like (x&&y)&&z, but the result would be the same if it had been required to parse like x&&(y&&z). -- Mark Brader "What a strange field. Studying beings instead of mathematics. Toronto Could lead to recursive problems in logic."
My text in this article is in the public domain. --
|
Mon, 11 Feb 2002 03:00:00 GMT |
|
 |
Salter #7 / 18
|
 Associativity and Commas - a plea for help!
Quote:
> (Sorry if this has been sent twice, but i`m using dejanews.com, which > sucks hard.) > Hi! > I`m a fairly strong C programmer, but i have a few queries that i`m > sure someone here can help me with. I`m really after > short explanations, a ptr to an on-line tutorial or book that will > explain. > 1) The comma operator. I dont have any C books in front of me, but > aren`t comma operators used to specify the execution order of a series > of steps (expressions?). I`ve used : > ... > for (i=0,j=28;i<100;i++) > ... > but only in for loops. Does it have any other uses? ( I dont mean > seperating parameters to functions, initialising arrays etc, i mean > specifically in specifying order of execution. I dont see any examples > that i understand. Can you use commas to solve problems like : > i = j + j++ + j; > where the compiler is free to evaluate the expression however it wishes?
One way I sometimes use it is in conditional statements: if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) { which I would need to write as two separate test without a , operator. This saves whitespace on the left. As others have answered, your example is broken beyond repair, and a ',' won't help. Why not write i = 3*j++ ? Michiel Salters --
|
Mon, 11 Feb 2002 03:00:00 GMT |
|
 |
Francis Glassboro #8 / 18
|
 Associativity and Commas - a plea for help!
Quote: >but the compiler could implement this by calling c() first, then >a(), then b(), then d() -- or any other order -- as long as it >produces the same final number to put into "x".
Or even a different one (for example where the return values of a() and b() depend on a global value (more options if they have parameters that include pointers) that they modify. Francis Glassborow Journal Editor, Association of C & C++ Users 64 Southfield Rd Oxford OX4 1PA +44(0)1865 246490 All opinions are mine and do not represent those of any organisation --
|
Mon, 11 Feb 2002 03:00:00 GMT |
|
 |
Francis Glassboro #9 / 18
|
 Associativity and Commas - a plea for help!
Quote: >One way I sometimes use it is in conditional statements: >if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) { >which I would need to write as two separate test without a , operator. >This saves whitespace on the left.
??? but the result of doing that is to evaluate (for side effects) the left operand but return the value of the right operand. Quote: >As others have answered, your example is broken beyond repair, >and a ',' won't help. Why not write i = 3*j++ ?
Francis Glassborow Journal Editor, Association of C & C++ Users 64 Southfield Rd Oxford OX4 1PA +44(0)1865 246490 All opinions are mine and do not represent those of any organisation --
|
Tue, 12 Feb 2002 03:00:00 GMT |
|
 |
Salter #10 / 18
|
 Associativity and Commas - a plea for help!
Quote:
> >One way I sometimes use it is in conditional statements: > >if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) { > >which I would need to write as two separate test without a , operator. > >This saves whitespace on the left. > ??? but the result of doing that is to evaluate (for side effects) the > left operand but return the value of the right operand.
Yes - what's so strange about that? The &result suggests that result may be modified, and that's what I intended. The idea is that ExpensiveTest will set result.member . Now, if that is a function not under my control, or it is used in many places, I can't just make it return result.member . This form does allow me to test the "pseudo-return" value. An example would be a database read. I can't change the database access functions, they often put their results in caller-allocated memory, and they might be quite expensive. Michiel Salters --
|
Sat, 16 Feb 2002 03:00:00 GMT |
|
 |
Dave Hans #11 / 18
|
 Associativity and Commas - a plea for help!
Quote:
>> >One way I sometimes use it is in conditional statements: >> >if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) { >> >which I would need to write as two separate test without a , operator. >> >This saves whitespace on the left. >> ??? but the result of doing that is to evaluate (for side effects) the >> left operand but return the value of the right operand. >Yes - what's so strange about that? The &result suggests that result may be >modified, and that's what I intended. The idea is that ExpensiveTest will >set result.member . Now, if that is a function not under my control, or it is >used in many places, I can't just make it return result.member . This form >does allow me to test the "pseudo-return" value.
But remember that the comma operator has the lowest precedence, lower even than &&, so your snippet above is parsed as (making the obvious abbreviations for brevity's sake). if ((T && E(&r)), r.m==s) rather than if (T && (E(&r), r.m==s)) which is what you seem to want. Regards, -=Dave Just my (10-010) cents I can barely speak for myself, so I certainly can't speak for B-Tree. Change is inevitable. Progress is not. --
|
Sun, 17 Feb 2002 03:00:00 GMT |
|
 |
Francis Glassboro #12 / 18
|
 Associativity and Commas - a plea for help!
Quote: >Yes - what's so strange about that? The &result suggests that result may be >modified, and that's what I intended. The idea is that ExpensiveTest will >set result.member . Now, if that is a function not under my control, or it is >used in many places, I can't just make it return result.member . This form >does allow me to test the "pseudo-return" value.
OK. I see what you are doing, it is just that this kind of overly complicated statement frequently leads to trouble. Why not move everything to the left of the sequence operator to before the if?
Francis Glassborow Journal Editor, Association of C & C++ Users 64 Southfield Rd Oxford OX4 1PA +44(0)1865 246490 All opinions are mine and do not represent those of any organisation --
|
Sun, 17 Feb 2002 03:00:00 GMT |
|
 |
pallex.. #13 / 18
|
 Associativity and Commas - a plea for help!
Thanks to everyone who posted a response. To save me sending 5 messages i`ll take the liberty of replying here, in one go! Sunil Rao: Quote: > The comma is a sequence point, which basically means that
any side-effects are guaranteed to be complete by then you "move past" the comma operator. Which is much more clear than any book i`ve read about it. I had no idea it was that simple! Cheers! Oleg Goldshmidt: Quote: > It seems to me that both your questions indicate that you would like > to be clever in your programming, and use the facilities of the > language to the limit. If that is the case (and maybe it isn't), > be warned that it is a bad idea. Don't write clever code, write > clear one.
No, I hate needlessly clever code too. I always try to write clearly, show precedence with brackets, use curly braces for one line `if` conditions where they`re not needed etc. I wanted to know so i could decode other peoples code! Quote: > Another possible use for comma is when the order of operations is > very clear, such as in the swap (UNTESTED): > void swap(int *x, int *y) > { > int tmp; > tmp = *x, *x = *y, *y = *x; > } > I personally don't see any advantage in this over 3 separate
statements." Me neither, and i`d never write it that way. Quote: > When precedence is the same, the associativity rules are used.
Thats all i need to know! Thanks! Chris Torek: Wow! Thanks for that (your post about expression parsing etc). Basically i`ve occasionally seen hairy looking recursive code for evaluating expressions, and even `simple` ones which dont have variables look reasonably intimidating, and your little essay prompted me to go and buy a book on data structures, algorithms etc which covers it. Michiel Salters: Quote: > i = j + j++ + j; > where the compiler is free to evaluate the expression however it
wishes? Quote: >As others have answered, your example is broken beyond repair, >and a ',' won't help. Why not write i = 3*j++ ?
Not the same. i=3*j++ wont necessarily work (undefined behaviour). If you evaluate from left to write here, trying with j=1, you get: i = 1 + 1 + 2 But i agree, i wasnt suggesting you should actually write code like that; i just wondered if it was a case where the comma operator would/could help, and it seems the answer is that it would, but that its better to just write individual lines. ---------- There was also a bit of a debate about: Quote: > if( TestNeedstobeDone && ExpensiveTest
(&result),result.member==somevalue) { which I thought was just saying : if ( (TestNeedstobeDone && ExpensiveTest(&result)) && (result.member==somevalue) ) { or even more clearly : if (TestNeedstobeDone && ExpensiveTest(&result)) { if (result.member==somevalue) { (Ie, the comma (sequence) operator and the boolean AND (and OR) operators both deal with this expression from left to right, guaranteeing that we wont get a page fault (or whatever) when we dereference the (undefined, almost certainly meaningless) `result` variable) but which provoked the response : Quote: > OK. I see what you are doing, it is just that this kind of overly > complicated statement frequently leads to trouble. Why not move > everything to the left of the sequence operator to before the if?
Do you mean as per my second example? ---------- Thanks again for all your help,
Sent via Deja.com http://www.deja.com/ Share what you know. Learn what you don't. --
|
Sun, 17 Feb 2002 03:00:00 GMT |
|
 |
Dave Hans #14 / 18
|
 Associativity and Commas - a plea for help!
[...] Quote: >There was also a bit of a debate about: >> if( TestNeedstobeDone && ExpensiveTest >(&result),result.member==somevalue) { >which I thought was just saying : >if ( (TestNeedstobeDone && ExpensiveTest(&result)) && > (result.member==somevalue) ) { >or even more clearly : >if (TestNeedstobeDone && ExpensiveTest(&result)) >{ > if (result.member==somevalue) > {
But that's not what it says. It's closer to if (TestNeedstobeDone) ExpensiveTest(&result); if (result.member==somevalue) { In other words, the comma operator has the lowest precedence. Of anything. So your statement gets parsed as if ( (TestNeedstobeDone&&ExpensiveTest(&result)), result.member==somevalue ) rather than if (TestNeedstobeDone && (ExpensiveTest(&result),result.member==somevalue) ) which appears to be what you want. If this is what you want, you need the extra parentheses. [...] Quote: >but which provoked the response : >> OK. I see what you are doing, it is just that this kind of overly >> complicated statement frequently leads to trouble. Why not move >> everything to the left of the sequence operator to before the if? >Do you mean as per my second example?
No, more like mine. Francis (I think this was his response) thought you wanted that. If that is indeed what you want, he's right, the statement is overly complicated. If it's not what you want, that just *proves* the statement is overly complicated. ;-) Regards, -=Dave Just my (10-010) cents I can barely speak for myself, so I certainly can't speak for B-Tree. Change is inevitable. Progress is not. --
|
Sat, 23 Feb 2002 03:00:00 GMT |
|
|
Page 1 of 2
|
[ 18 post ] |
|
Go to page:
[1]
[2] |
|