dgh%dgh@Sun.COM (David Hough) (01/10/88)
I didn't think X3J11 would ever go for it, but now Doug Gwyn at least says he might support adding a power operator IF ANSI C has to go through a third public review period for some OTHER reason. With that degree of encouragement (coupled with the recent outpouring on comp.lang.c on this subject) I've added the following item to my list of 25 suggestions to be submitted to X3J11 at the next public review. Interestingly enough, although over 100 mathematical software people have looked at previous versions of my commentary, none of them so far has made a big deal about a power operator. Like me, they may not have thought it would ever be accepted. Comment #9, Section 3.3.4: add power operator for ------- - ------- - - - --- ----- -------- --- integral exponents -------- --------- C does not provide a power or exponentiation operator, like Pascal (which however provides a squaring operator), but unlike Fortran ** or Basic ^ . C's original system programming motivation does not require such an operator, and C's general approach is that operations that can not be implemented in a few machine instructions should be invoked as functions. Based on Fortran experience, this is excellent design; it discourages the common Fortran codings "x**0.5" and "x**2.0". Conversely, omitting an easy way to say "x**2" for complicated expressions x is a C oversight that adds gratuitous complexity to code. The complexity of general exponentiation to a floating-point power is sufficiently attested by the fact that such an operator was dropped from the final MC68881 architecture due to lack of microcode space in the initial implementation. Therefore I don't advocate that C add an operator notation for floating-point powers (although later -------- I advocate that pow() be made an operator in functional ---------- notation). I do advocate that an operator notation for exponentiation to integral powers be added. That some convenient syntax be standardized is more important than the specific syntax, and X3J11 is probably best qualified to choose from various alternative candidates such as **, ^^, ->, etc. Anybody who has written x**y or x ** y in old C code, intending x * *y, has probably done some other things that won't pass an ANSI C compiler. But ANSI C could be defined to accept x**y in its old meaning as well as x**y in its new since y must be a pointer in the first case and an integral expression in the second. But I doubt that's worthwhile. To best correspond to the usage of mathematics and other computer languages, the precedence of ** must be greater than that of a multiplicative or additive operator. Recommendation: Add a power operator **, with the -------------- precedence of a cast operator, so that a cast expression can be cast-expression ** cast-expression In b ** n, the base expression b may be an integral or floating expression, but the exponent expression n must be an integral expression. If n == 0, then the result is 1 cast to the type of b. If n > 0, then the result is the usual: the value of b is multiplied together n-1 times. If n < 0, then the result is the reciprocal of b ** (-n), which is 0 if b is an integral expression >= 2. Note that unlike other operators, the "usual arithmetic conversions" are not made to b and n; the type of the result is always that of b. The Rationale should encourage compilers to be clever when n is constant -1, 0, 1, or 2, but not so clever with other n that the intermediate results overflow or underflow unnecessarily. The Rationale should also encourage compilers to compute, wherever possible, "x * b ** n" by a shift instruction when b is the base of integer arithmetic, and by ldexp(x,n) when b is the base of floating-point arithmetic. David Hough ARPA: dhough@sun.com UUCP: {ucbvax,decvax,allegra,decwrl,cbosgd,ihnp4,seismo}!sun!dhough
dik@cwi.nl (Dik T. Winter) (01/10/88)
In article <38384@sun.uucp> dgh%dgh@Sun.COM (David Hough) writes: > Recommendation: Add a power operator **, with the > -------------- > precedence of a cast operator, so that a cast expression can > be > > cast-expression ** cast-expression > > In b ** n, the base expression b may be an integral or > floating expression, but the exponent expression n must be > an integral expression. If n == 0, then the result is 1 > cast to the type of b. If n > 0, then the result is the usual: > the value of b is multiplied together n-1 times. If n < 0, > then the result is the reciprocal of b ** (-n), which is 0 > if b is an integral expression >= 2. Note that these semantics are wrong. What if n<0 and b**(-n) overflows while b**n does not underflow? According to the stated semantics this should trap an overflow or return 0.0. On the other hand if b**n for negative n is defined as (1/b)**(-n) we lose precision. So is there anybody who can come up with a proper definition of the power operator? -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
ix426@sdcc6.ucsd.EDU (tom stockfish) (01/11/88)
In article <38384@sun.uucp> dgh%dgh@Sun.COM (David Hough) writes: > Recommendation: Add a power operator **, with the > -------------- >precedence of a cast operator, so that a cast expression can >be > > cast-expression ** cast-expression > >In b ** n, the base expression b may be an integral or >floating expression, but the exponent expression n must be >an integral expression. > >David Hough This proposal will never fly as it stands. 1. It is not in the spirit of C. Unlike any other C operator, a lexical analyzer will not be able to recognize it, since it is indistinguishable from very common pointer declarations, e.g., "char **argv". 2. The meaning of C expressions is almost always independent of white space. The one exception being a+++b versus a+ ++b. Even this one, however, is disambiguated by the "the longest possible token is the next one" rule. You would have to invent something else to disambiguate x ** y from x * (*y). 3. I'm not sure what precedence/associativity you have chosen for "**". From your posting I assume you mean that (double)2 ** 3 should group as ( (double)2 ) ** 3. This is disastrous. Since unary minus has the same precedence as casts, -x**2 + x - 10 would have to group as (-x) ** 2 + x - 10 which is equivalent to x**2 + x - 10. (The arbitrary precision language bc(1) actually has this precedence! Has any other numeric user used bc for serious work? I'd like to swap bug lists with you.) What associativity did you plan for "**"? Left to right, or right to left? All other binary operators are left to right, but this would be trivial for "**" since it would just collapse the exponents together: (x**y)**z == x**(y*z). Right to left associativity would be more useful, but would break the general rule for other C operators. You could make it non-associative like fortran originally did, but then it would be C's only non-associative operator. I think a good proposal would give the power operator a precedence above unary and below primary, with right to left associativity (I believe this is how fortran currently has it). The only thing left to decide is how it interacts with pre- or post-fix ++,--, and I'm not sure how that should be done. This should be well thought ought, and preferably implemented in some compiler, before a proposal is submitted to X3J11. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
karl@haddock.ISC.COM (Karl Heuer) (01/14/88)
In article <38384@sun.uucp> dgh%dgh@Sun.COM (David Hough) writes: >Comment #9, Section 3.3.4: add power operator for integral exponents As you said, ANSI can pick whatever syntax they want; but to avoid ambiguity Let's use "*^" when we're just arguing semantics. I've edited the quoted material accordingly. >To best correspond to the usage of mathematics and other computer languages, >the precedence of *^ must be greater than that of a multiplicative or >additive operator. If this were the only criterion, I'd say it should be put into a new precedence class between unary and multiplicative. However, this makes -x*^2 mean the "wrong" thing. If this is a problem (apparently bc users don't mind), my recommendation is to give it a precedence between postfix unary and prefix unary. (Note that "->id", ".id", "[expr]", and "(arglist)" can all be considered postfix unary, just as "(type)" can be considered prefix unary.) More precisely: power-expression: postfix-expression postfix-expression *^ cast-expression unary-expression: power-expression ++ unary-expression -- unary-expression unary-operator cast-expression sizeof unary-expression sizeof ( type-name ) (Also, "*^=" should be added to the list of assignment operators.) >Note that unlike other operators, the "usual arithmetic conversions" are not >made to b and n; the type of the result is always that of b. I'd like to mention that there is already a precedent: 1<<1L is 2, not 2L. >If n < 0, then the result is the reciprocal of b *^ (-n), which is 0 if b is >an integral expression >= 2. I think 2 *^ -1 should be undefined (as is 1 << -1), rather than zero. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
dricej@drilex.UUCP (Craig Jackson) (01/18/88)
As a side note to this discussion: many people have put the famous
a+++b as one of the few seemingly ambiguous parts of C. But a few years
ago, a colleague of mine found a bigger one: dividing by a de-referenced
pointer:
{
double a,b,*pc;
. . . Give everything values
a = b/*c;
. . . rest of program
}
My friend spent two days looking for that one...'fortutunately', he didn't
comment the rest of the code, so he did get an 'unexpected EOF' message.
Just think of how long it would have taken to find the problem in
well-commented code.
--
Craig Jackson
UUCP: {harvard!axiom,linus!axiom,ll-xn}!drilex!dricej
BIX: cjackson
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/18/88)
In article <434@drilex.UUCP> dricej@drilex.UUCP (Craig Jackson) writes: > a = b/*c; >My friend spent two days looking for that one... Did your friend learn his lesson and start using white space?
ok@quintus.UUCP (Richard A. O'Keefe) (01/18/88)
In article <434@drilex.UUCP>, dricej@drilex.UUCP (Craig Jackson) writes: > > a = b/*c; > > My friend spent two days looking for that one... When I've spent more than a few minutes on such a problem I use 'cc -E foo.c | cb' or 'cc -E foo.c | indent' depending on which system I'm on to see exactly what the preprocessor has done with it. This strips out comments too, which is why it's a good dodge for this kind of problem. (Couldn't happen in BCPL...) On UNIX, it's a good idea to have a little script around: #!/bin/sh #NAME badcom #SYNOPSIS badcom foobaz.c #DESCRIPTION Finds (some) suspicious comment lines, namely # lines where /* occurs, is not the first thing # on its line, and hasn't got */ on the same line, # also lines where */ occurs, is not the last # thing on the line, and hasn't got /* on the # same line #OPTIONS none #BUGS Doesn't know about ".." or #if 0 # Misses other kinds of comment error egrep -n -e '[^ \t].*/\*|\*/.*[^ \t]' $1 | \ egrep -v -e '/\*.*\*/' {When entering this script, replace \t by actual TAB characters.}
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/19/88)
In article <2252@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: > >mean the "wrong" thing. If this is a problem (apparently bc users don't >mind), my recommendation is to give it a precedence between postfix unary and >prefix unary. (Note that "->id", ".id", "[expr]", and "(arglist)" can all be >considered postfix unary, just as "(type)" can be considered prefix unary.) >More precisely: > >power-expression: > postfix-expression > postfix-expression *^ cast-expression > >unary-expression: > power-expression > ++ unary-expression > -- unary-expression What about 'unary-expression ++'? Currently, this is on the same level as pre-incrementing with the distinction being associativity. Would you split these two and put power between them? Also, what would the associativity be for power? Would 2 *^3 *^5 be equal to 2 *^ 15 or to 2 *^ 243? >I think 2 *^ -1 should be undefined (as is 1 << -1), rather than zero. Since we are defining the 'power' operator and not the 'integer power' operator, 2 *^ (-1) should return (double)0.5 and then be demoted to an integer class, if necessary. The power operator should not return two different numbers (other than with respect to precision) based on the types of the arguments. This is one of the major reasons I don't like the intro of the power operator into C. (BTW, maybe ANSI should define (1 << -1) as right-shifting by 1--any response to this out there?) Your example (2 *^-1, no parentheses around -1) is undefined because of the way you defined your precedence; i.e., 2 *^ -1 groups as (2 *^ -) 1 (sort of). -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
ONGKENTH%NUSVM.BITNET@CUNYVM.CUNY.EDU (kenneth ong) (01/19/88)
please remove me from the info-c list. thanks!
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/20/88)
In article <2252@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
.
.If this were the only criterion, I'd say it should be put into a new
.precedence class between unary and multiplicative. However, this makes -x*^2
.mean the "wrong" thing. If this is a problem (apparently bc users don't
.mind), my recommendation is to give it a precedence between postfix unary and
.prefix unary. (Note that "->id", ".id", "[expr]", and "(arglist)" can all be
.considered postfix unary, just as "(type)" can be considered prefix unary.)
Looking at my chart on precedence and associativity, I noticed that all the
unary operators are grouped together, group right to left, and are above all
the binary operators. Putting the power operator above the unary operators
would produce lots of uncompilable statements;i.e., (++a POW ++b) would be
illegal. (Note: I do not consider (), [], ., or -> to be either unary or
binary; they are special operators and cannot be grouped in with the other
unary operators). As I have said before, I do not believe that we should split
up the unary operators; too many programs are dependent on the fact that they
all have the same precedence (splitting the unaries into prefix and postfix
groups would fix the example above, however).
.I think 2 *^ -1 should be undefined (as is 1 << -1), rather than zero.
One of the reasons I can't agree with this is that 2 *^ ((float)(-1)) would
work, but 2 *^ (-1) would not. (I stated in another article what I believe 2
*^ (-1) should do *IF* we were to add the power operator, which I am against
doing.)
--
_ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194
' ) ) "The secret compartment of my ring I fill
/ / _ , __o ____ with an Underdog super-energy pill."
/ (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
karl@haddock.ISC.COM (Karl Heuer) (01/20/88)
In article <3421@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >In article <2252@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >>power-expression: >> postfix-expression >> postfix-expression *^ cast-expression >> >>unary-expression: >> power-expression >> ++ unary-expression >> -- unary-expression [ unary-operator cast-expression ] >What about 'unary-expression ++'? Currently, this is on the same level as >pre-incrementing with the distinction being associativity. That's the way it's usually described, but an equivalent formulation is that postfix unary has a higher precedence than prefix unary (and there's no need to talk about "associativity" of a unary operator). This is already in the ANSI grammar at the "postfix-expression" level. >Would you split these two and put power between them? Yes. That's what I said in the grammar as well as the English text. >Also, what would the associativity be for power? [2 *^ 3 *^ 5] I believe the grammar is unambiguous. Omitting a few trivial productions, expression("2*^3*^5") power-expression("2*^3*^5") postfix-expression("2") *^ cast-expression("3*^5") unary-expression("3*^5") power-expression("3*^5") postfix-expression("3") *^ cast-expression("5") Thus, the parsing is 2*^(3*^5). It can't parse as (2*^3)*^5 because "2*^3" (without parens) is not a postfix-expression. >>I think 2 *^ -1 should be undefined (as is 1 << -1), rather than zero. > >Since we are defining the 'power' operator and not the 'integer power' >operator, 2 *^ (-1) should return (double)0.5 and then be demoted >to an integer class, if necessary. The power operator should not return two >different numbers ... based on the types of the arguments. This is one of >the major reasons I don't like the intro of the power operator into C. Actually, we are defining several operators which share a common symbol. Just as the "/" symbol invokes the integer-divide operator when both operands are integers (it most certainly does *not* invoke floating-point divide and then truncate the result), "*^" should invoke the integer-power operator when both operands are integers. I thought that was the whole point! >Your example (2 *^-1, no parentheses around -1) is undefined because of the >way you defined your precedence; i.e., 2 *^ -1 groups as (2 *^ -) 1 (sort of). I already thought of that problem. It's covered by the grammar. power-expression("2*^-1") postfix-expression("2") *^ cast-expression("-1") unary-expression("-1") unary-operator("-") cast-expression("1") >(BTW, maybe ANSI should define (1 << -1) as right-shifting by 1--any >response to this out there?) Bad idea. It would require the compiler to generate extra code if the right operand is nonconstant. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
nevin1@ihlpf.ATT.COM (00704A-Liber) (01/22/88)
In article <2335@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <3421@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >>What about 'unary-expression ++'? Currently, this is on the same level as >>pre-incrementing with the distinction being associativity. > >That's the way it's usually described, but an equivalent formulation is that >postfix unary has a higher precedence than prefix unary (and there's no need >to talk about "associativity" of a unary operator). This is already in the >ANSI grammar at the "postfix-expression" level. Not entirely true. Expressions such as *--pointer still require knowledge of associativity to be correctly evaluated. But I think that you are right about being able to split up postfix and prefix (I'll have to think about it some more). > >>Would you split these two and put power between them? > >Yes. That's what I said in the grammar as well as the English text. Assuming this is your order (from highest to lowest): 1. (); []; .; -> (left to right) 2. postfix unary (right to left) 3. power (right to left) 4. prefix unary (right to left) 5. *; /; % (left to right) 6 and below. the same as K&R Then --a power --b cannot be done. It would be grouped as (-- ((a power --) b), which is illegal. If power were to be added (PLEASE DON'T), I believe it should have a precedence below the unaries but above {*; /; and %) and associate left to right; it would match closer to the mathematical definition this way. Also, notice that all the right to left operators are either assignment or unary; having an augmented assignment operator for an operator which groups right to left seems inconsistent (and if power is to be added the corresponding augmented operator should be added, too). Also , by your method (++a pow b) == ++(a pow b) and (a pow b++) == (a pow (b++)) are how groupings would be done. This does not look intuitive at all. > >>>I think 2 *^ -1 should be undefined (as is 1 << -1), rather than zero. >> >>Since we are defining the 'power' operator and not the 'integer power' >>operator, 2 *^ (-1) should return (double)0.5 and then be demoted >>to an integer class, if necessary. The power operator should not return two >>different numbers ... based on the types of the arguments. This is one of >>the major reasons I don't like the intro of the power operator into C. > >Actually, we are defining several operators which share a common symbol. Just >as the "/" symbol invokes the integer-divide operator when both operands are >integers (it most certainly does *not* invoke floating-point divide and then >truncate the result), "*^" should invoke the integer-power operator when both >operands are integers. I thought that was the whole point! Good point here. But, I would rather have (2 pow (-1)) evaluate to 0, (1 pow (-1)) evaluate to 1 than to just be 'undefined'; i.e., crash my program! >>way you defined your precedence; i.e., 2 *^ -1 groups as (2 *^ -) 1 (sort of). >I already thought of that problem. It's covered by the grammar. > >power-expression("2*^-1") >postfix-expression("2") *^ cast-expression("-1") > unary-expression("-1") > unary-operator("-") cast-expression("1") > Then you are not clearly defining the precedence, in English. Please describe precisely how you want evaluation to go. >>(BTW, maybe ANSI should define (1 << -1) as right-shifting by 1--any >>response to this out there?) > >Bad idea. It would require the compiler to generate extra code if the right >operand is nonconstant. What does it do now if the the right operand is negative and inside a variable or an expression? -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
karl@haddock.ISC.COM (Karl Heuer) (01/23/88)
In article <3474@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >>an equivalent formulation is that postfix unary has a higher precedence than >>prefix unary (and there's no need to talk about "associativity" of a unary >>operator). > >Not entirely true. Expressions such as *--pointer still require knowledge of >associativity to be correctly evaluated. No, it's completely unambiguous. You seem to be thinking that, unless some type of "associativity" is defined, it will parse as (* --) pointer. That doesn't make sense, because "*" expects an expression (not another operator) as its operand. Even if "*" had a higher precedence than "--", it would still parse correctly. Or to put it another way, that's not what *I* mean by associativity. >Assuming this is your order (from highest to lowest): >1. (); []; .; -> (left to right) >2. postfix unary (right to left) >3. power (right to left) >4. prefix unary (right to left) >5. *; /; % (left to right) >6 and below. the same as K&R Yes, except that classes 1 and 2 can be combined, as in the ANSI grammar. >Then --a power --b cannot be done. It would be grouped as >(-- ((a power --) b), which is illegal. It would not be grouped that way, because (a *^ --) is not a valid parsing. >>I already thought of that problem [2 *^ -1]. It's covered by the grammar. >> >>power-expression("2*^-1") >>postfix-expression("2") *^ cast-expression("-1") >> unary-expression("-1") >> unary-operator("-") cast-expression("1") >> >Then you are not clearly defining the precedence, in English. Please describe >precisely how you want evaluation to go. I included the grammar fragment as the precise definition. You want English? "*^ has a lower precedence than postfix unary, but higher than prefix unary." I don't think I can make it any clearer. >If power were to be added (PLEASE DON'T), I believe it should have a >precedence [just below unary] and associate left to right; it would match >closer to the mathematical definition this way. Think again -- the mathematical definition is right to left. >Also, notice that all the right to left operators are either assignment or >unary; And the ternary operator. >having an augmented assignment operator for an operator which groups right to >left seems inconsistent (You've lost me. It's inconsistent for both *^ and *^= to be R-to-L?) I don't see any problem with this. I figure that the reason "/" is L-to-R is because that makes better mathematical sense; for the same reason, "*^" should be R-to-L. >Also , by your method >(++a pow b) == ++(a pow b) >and >(a pow b++) == (a pow (b++)) >are how groupings would be done. This does not look intuitive at all. I agree. But if "++" and "-" are to have the same precedence, one can't have "++a *^ 2" and "- a*^2" both do the right thing. After rethinking this, I've decided that it's not so important for "- a*^2" to work (and it could be caught by lint, anyway). So the best precedence would probably be just below unary, as you said. The revised grammar would be: power-expression: cast-expression cast-expression *^ power-expression multiplicative-expression: power-expression multiplicative-expression * power-expression multiplicative-expression / power-expression multiplicative-expression % power-expression >>>>I think 2 *^ -1 should be undefined (as is 1 << -1), rather than zero. > >... I would rather have (2 pow (-1)) evaluate to 0, (1 pow (-1)) evaluate to >1 than to just be 'undefined'; i.e., crash my program! The question is, would anybody ever use int-expr *^ negative-int-expr and depend on the result being zero? I'd think that such a situation is probably a program error anyway, in which case it doesn't matter what happens. >>>(BTW, maybe ANSI should define (1 << -1) as right-shifting by 1--any >>>response to this out there?) >> >>Bad idea. It would require the compiler to generate extra code if the right >>operand is nonconstant. > >What does it do now if the the right operand is negative and inside a variable >or an expression? Officially, it's "undefined". In practice, you get whatever the architecture gives you. On some, it really is a right shift; on others, you get zero. There may even be some where it causes a trap. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
karl@haddock.ISC.COM (Karl Heuer) (01/23/88)
In article <3461@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: >In article <7139@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >>... the squaring operator (expr ** 2) is quite heavily used. > >Yes, but if you know that you are going to be squaring you can replace it >with (expr * expr) (possibly needing temp variables depending on the side >effects concerning expr) That's the point -- having to use the temp variables is a pain. If the only expressions I ever wanted to square were simple variables, I wouldn't mind using the multiply. It's because of the things with side effects (or even side-effect-free expressions that are complicated) that we want a power op. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
ix426@sdcc6.ucsd.EDU (tom stockfish) (01/23/88)
In article <3474@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704A-Liber,N.) writes: > _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 > >1. (); []; .; -> (left to right) >2. postfix unary (right to left) >3. power (right to left) >4. prefix unary (right to left) >5. *; /; % (left to right) >6 and below. the same as K&R > >.... If power were to be added (PLEASE DON'T), I believe it >should have a precedence below the unaries but above {*; /; and %) and >associate left to right; it would match closer to the mathematical definition >this way. No, please don't propose this precedence. Expressions like -x*^2 + 5 will occur often and will make people hate C (where "*^" is the proposed power op). Any power operator proposal *must* get this one right. >Also, notice that all the right to left operators are either >assignment or unary; Wrong. "? :" groups right to left (K&R appendix notwithstanding). >having an augmented assignment operator for an operator >which groups right to left seems inconsistent (and if power is to be added the >corresponding augmented operator should be added, too). This seems pretty trivial. It follows the rule a OP= b <==> a = a OP b (except for side effects) just fine, which is good enough for me. >Also , by your method >(++a pow b) == ++(a pow b) >and >(a pow b++) == (a pow (b++)) >are how groupings would be done. This does not look intuitive at all. Of course not. Neither does a+b / c+d You would write these (if you ever did) as ++ a*^b /* illegal */ or (++a)*^b and a *^ b++ . I would never try to guess intuitively how "*^" interacted with "++"/"--" without looking it up in the standard. Even then, I would add parens since this would be such an unusual situation. The expression -x*^2 + 5 is an entirely different (and far more important) matter. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
nevin1@ihlpf.ATT.COM (00704a-Liber) (01/28/88)
In article <2370@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: .>In article <7139@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: .>>... the squaring operator (expr ** 2) is quite heavily used. . .That's the point -- having to use the temp variables is a pain. If the only .expressions I ever wanted to square were simple variables, I wouldn't mind .using the multiply. It's because of the things with side effects (or even .side-effect-free expressions that are complicated) that we want a power op. That is what macros are for! And a good optimizing compiler should get rid of those variables when you are squaring simple variables. The storage of the value has to be made somewhere; I don't think it should be implicit when the optimized code produced should be about the same either way. -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
karl@haddock.ISC.COM (Karl Heuer) (01/29/88)
In article <2397@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <3594@sdcc6.ucsd.EDU> ix426@sdcc6.ucsd.edu.UUCP (tom stockfish) writes: >>No, please don't propose this precedence ["*^" just above "*"]. Expressions >>like "-x*^2 + 5" will occur often and will make people hate C.... Any power >>operator proposal *must* get this one right... > >[The alternative is worse, so] it looks like the solution is to write your >example as either "5 - x*^2" or "-(x*^2) + 5" ... It occurs to me that there is a third plausible precedence, which does the "right" thing for the usual examples without breaking existing code. 1. postfix operators ("primary" and "postfix unary") 2. prefix operators other than unary minus 3. exponentiation 4. unary minus 5. multiplicative operators The drawback is that it creates *two* new precedence levels, by introducing exponentiation and splitting off unary minus. Is it worth it? I dunno. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint