rtm@christmas.UUCP (Richard Minner) (01/25/91)
In article <1991Jan23.015757.22220@portia.Stanford.EDU> fangchin@portia.Stanford.EDU (Chin Fang) writes: >... from my /usr/include/limits.h >#define INT_MIN -2147483648 /* min decimal value of an "int" */ Something I've been curious about, should the above be #define INT_MIN (-2147483648) The precedence rules seem to imply that ()'s aren't needed with a negative integer constant. Could someone confirm or deny this please? (I always use ()'s out of habit.) -- Richard Minner rtm@island.COM {uunet,sun,well}!island!rtm Island Graphics Corporation Sacramento, CA (916) 736-1323
ccplumb@rose.uwaterloo.ca (Colin Plumb) (01/28/91)
rtm@island.COM (Richard Minner) wrote: >> #define INT_MIN -2147483648 /* min decimal value of an "int" */ > > Something I've been curious about, should the above be > #define INT_MIN (-2147483648) > > The precedence rules seem to imply that ()'s aren't needed > with a negative integer constant. Could someone confirm or > deny this please? (I always use ()'s out of habit.) Well, unary - has higher precedence than anything except the postfix opertors: [expression] (argument-list) .identifier ->identifier ++ -- Now, none of these are applicable to intergers, so it's safe... except! As all loyal followers of the Obfuscated C code contest know, array[i] == *(array+i) == *(i+array) == i[array]. So #define X1 -10 #define X2 (-10) int i, foo[50]; int *p = &foo[25]; for (i = 0; i < 50; i++) foo[i] = i; printf("%d, %d\n", X1[p], X2[p]); Will print "-35, 15". If onbody's used this particular perversion in the obfuscated C code contest yet, I'm sure they will soon. -- -Colin
gwyn@smoke.brl.mil (Doug Gwyn) (01/28/91)
In article <33@christmas.UUCP> rtm@island.COM (Richard Minner) writes: >Something I've been curious about, should the above be >#define INT_MIN (-2147483648) Yes. >The precedence rules seem to imply that ()'s aren't needed >with a negative integer constant. There are contexts that could cause trouble, e.g. "x-INT_MIN" or "x=INT_MIN". While the C standard requires that these work as expected, many older C implementations will misinterpret these.
gwyn@smoke.brl.mil (Doug Gwyn) (01/28/91)
In article <1991Jan27.233142.28302@watdragon.waterloo.edu> ccplumb@rose.uwaterloo.ca (Colin Plumb) writes:
-As all loyal followers of the Obfuscated C code contest know,
-array[i] == *(array+i) == *(i+array) == i[array]. So
-#define X1 -10
-#define X2 (-10)
-[...]
-printf("%d, %d\n", X1[p], X2[p]);
-Will print "-35, 15".
No, that's a ludicrous misinterpretation of the situation. The
compiler does NOT perform a textual "rewrite" of the [] expression
then reparse it.
dave@cs.arizona.edu (Dave P. Schaumann) (01/28/91)
In article <14999@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: |In article <1991Jan27.233142.28302@watdragon.waterloo.edu> ccplumb@rose.uwaterloo.ca (Colin Plumb) writes: |-As all loyal followers of the Obfuscated C code contest know, |-array[i] == *(array+i) == *(i+array) == i[array]. So |-#define X1 -10 |-#define X2 (-10) |-[...] |-printf("%d, %d\n", X1[p], X2[p]); |-Will print "-35, 15". | |No, that's a ludicrous misinterpretation of the situation. The |compiler does NOT perform a textual "rewrite" of the [] expression |then reparse it. This works as Colin says on my machine (compiling with gcc). Here is the full program: #include <stdio.h> #define X1 -10 #define X2 (-10) main(void) { int i, a[50], *p = &a[25] ; for( i = 0 ; i < 50 ; i++ ) a[i] = i ; printf( "X1:%d X2:%d", X1[p], X2[p] ) ; } If Colin's interpretation is wrong, what *is* happening? Dave Schaumann | And then -- what then? Then, future... dave@cs.arizona.edu | -Weather Report
krey@i30fs1.ira.uka.de (Andreas Krey) (01/29/91)
In article <745@caslon.cs.arizona.edu>, dave@cs.arizona.edu (Dave P. Schaumann) writes: > In article <14999@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: > |In article <1991Jan27.233142.28302@watdragon.waterloo.edu> ccplumb@rose.uwaterloo.ca (Colin Plumb) writes: > |-As all loyal followers of the Obfuscated C code contest know, > |-array[i] == *(array+i) == *(i+array) == i[array]. So > |-#define X1 -10 > |-#define X2 (-10) > |-[...] > |-printf("%d, %d\n", X1[p], X2[p]); > |-Will print "-35, 15". > | > |No, that's a ludicrous misinterpretation of the situation. The > |compiler does NOT perform a textual "rewrite" of the [] expression > |then reparse it. > > > This works as Colin says on my machine (compiling with gcc). Here is the > full program: > [ program deleted ] > > If Colin's interpretation is wrong, what *is* happening? > > Dave Schaumann | And then -- what then? Then, future... > dave@cs.arizona.edu | -Weather Report 'X1[p]' -> preprocessor -> '-10[p]' That is, by precedence rules, the same as '-(10[p])', same as '-(p[10])', which is 35 in the program above. The latter conversions are no textual 'rewrites'; the compiler simply reduces the a[b] first, then the -a. Thus array reference goes before negation and there is the negative sign. X2 on the other hand is parsed differently because of the braces around -10. (The [] is actually a commutative operator, although the concrete syntax may suggest otherwise.) Besides I nearly always brace all replacement texts with more than one token and all macro parameters within them, just to be sure. .signature: No such file or directory
gwyn@smoke.brl.mil (Doug Gwyn) (01/29/91)
In article <745@caslon.cs.arizona.edu> dave@cs.arizona.edu (Dave P. Schaumann) writes: >If Colin's interpretation is wrong, what *is* happening? What I assumed Colin was blaming the difference on was the rewrite rule, which is not the source of the difference. -10[p] and (-10)[p] are not the same due to [] having higher precedence than -. Colin's is another (this time strictly conforming) example illustrating that the parentheses in the macro definition DO matter. If that's what he intended to say, I apologize for misunderstanding.
lwj@cs.kun.nl (Luc Rooijakkers) (01/29/91)
In <14998@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <33@christmas.UUCP> rtm@island.COM (Richard Minner) writes: >>Something I've been curious about, should the above be >>#define INT_MIN (-2147483648) >Yes. This may have been the intention of the comittee. However, I cannot find such a guarantee: 2.2.4.2 Sizes of Integral Types <limits.h> The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. Now, an expression like -2147483648 certainly satisfies the above constraints. >>The precedence rules seem to imply that ()'s aren't needed >>with a negative integer constant. >There are contexts that could cause trouble, e.g. "x-INT_MIN" >or "x=INT_MIN". While the C standard requires that these work >as expected, many older C implementations will misinterpret >these. Right. As has been pointed out already, however, there are also contexts that can cause trouble where the standard requires it, e.g. INT_MIN[p] which expands to -2147483648[p] which is equivalent to -(2147483648[p]) Thus, I would conclude that INT_MIN cannot be used in this way in a strictly conforming program. Instead, (INT_MIN)[p] would have to be used. (This is an obscure corner of the language, I agree.) -- Luc Rooijakkers Internet: lwj@cs.kun.nl Faculty of Mathematics and Computer Science UUCP: uunet!cs.kun.nl!lwj University of Nijmegen, the Netherlands tel. +3180652271
debra@svin02.info.win.tue.nl (Paul de Bra) (01/29/91)
In article <33@christmas.UUCP> rtm@island.COM (Richard Minner) writes: >In article <1991Jan23.015757.22220@portia.Stanford.EDU> fangchin@portia.Stanford.EDU (Chin Fang) writes: >>... from my /usr/include/limits.h >>#define INT_MIN -2147483648 /* min decimal value of an "int" */ As James Clark reminded me a long time ago, -2147483648 is a (constant) expression, not evaluated by the preprocessor but by the compiler. This has 2 implications: 1) as people have said before, the replacement is purely textual, so the unary minus can be misused as a binary minus when writing something like 5 INT_MIN 2) this define is not supposed to work at all if 2147483648 is not a legal positive integer. (on most machines it isn't) if INT_MAX is 2147483647 then INT_MIN should not be written as -2147483648 but as (-2147483647-1) so your limits.h is at fault, and some compilers (including gcc) will not treat your INT_MIN as a large negative number, because of integral promotion. (2147483648 is promoted to unsigned because it is too large for a signed int) Paul. (debra@win.tue.nl, debra@research.att.com)
gwyn@smoke.brl.mil (Doug Gwyn) (01/30/91)
In article <2698@wn1.sci.kun.nl> lwj@cs.kun.nl (Luc Rooijakkers) writes: >In <14998@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >>In article <33@christmas.UUCP> rtm@island.COM (Richard Minner) writes: >>>Something I've been curious about, should the above be >>>#define INT_MIN (-2147483648) >>Yes. >This may have been the intention of the comittee. I wasn't trying to interpret the intention of X3J11; the fellow asked whether the implementation "should" parenthesize such definitions, and I said "Yes". I would hope that implementors would do so, and that programmers would not write INT_MIN[p] in their code.
nathan@elberton.inmos.co.uk (Nathan Sidwell) (01/31/91)
In article <14998@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <33@christmas.UUCP> rtm@island.COM (Richard Minner) writes: >>Something I've been curious about, should the above be >>#define INT_MIN (-2147483648) > >Yes. > >>The precedence rules seem to imply that ()'s aren't needed >>with a negative integer constant. > >There are contexts that could cause trouble, e.g. "x-INT_MIN" >or "x=INT_MIN". While the C standard requires that these work >as expected, many older C implementations will misinterpret >these. Well gcc -ansi doesn't, source is #define NUM -10 main() { int x; x = x-NUM; x = 1/**/2; } preprocessor output is main() { int x; x = x--10; x = 1 2; } which fails, note that it is partly correct as the /**/ has been reduced to a space. This is gcc 1.36, has it been fixed in later versions? Nathan Sidwell, INMOS Ltd, UK JANET: nathan@uk.co.inmos Generic disclaimer applies UUCP: ukc!inmos!nathan This space unintentionally filled INTERNET: nathan@inmos.com
torek@elf.ee.lbl.gov (Chris Torek) (02/14/91)
In article <1702@svin02.info.win.tue.nl> debra@svin02.info.win.tue.nl (Paul de Bra) writes: > if INT_MAX is 2147483647 then INT_MIN should not be written as > -2147483648 but as (-2147483647-1) Paul is correct here. The type and value of -2147483648 are unsigned long and 2147483648 respectively (on a typical two's complement 32-bit machine). The constant is made up of two subexpressions, namely unary minus and the integral constant `2147483648', and the latter is an unsigned long. Negation does not alter the type, and in this particular case it leaves the value unchanged as well. >-2147483648 is a (constant) expression, not evaluated by the preprocessor >but by the compiler. Actually, it is at times evaulated by both. The preprocessor has arithmetic that is similar to, but not the same as, that in the compiler. When I discovered this I raised a very minor fuss (a fusslet? fusslette? :-) ) since it complicates the preprocessor, which must understand unsigned values (including U-suffixed constants): #include <stdio.h> void a() { #if -1 > 1 printf("bad\n"); #else printf("good\n"); #endif } void b() { #if -1U > 1 printf("good\n"); #else printf("bad\n"); #endif } int main() { a(); b(); return 0; } must print `good' twice. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov