434,786 Members | 1,143 Online
Need help? Post your question and get tips & solutions from a community of 434,786 IT Pros & Developers. It's quick & easy.

# can you tell that y the code is work like that

 P: n/a int *p=20; printf("%d",*p); printf("%d",p); the above code prints the output as somegarbage value //for *p(may be address 20 //for p why can you explain thanks for that Nov 15 '05 #1
38 Replies

 P: n/a venkatesh, le 21/10/2005, a écrit : int *p=20; printf("%d",*p); printf("%d",p); the above code prints the output as somegarbage value //for *p(may be address 20 //for p why can you explain thanks for that int dummy = 20; int* p = &dummy; printf("%d\n",*p); printf("%p\n",p); or int* p = malloc(sizeof int); *p = 20; printf("%d\n",*p); printf("%p\n",p); -- Pierre Maurette Nov 15 '05 #2

 P: n/a venkatesh wrote: int *p=20; Broken. What makes you suspect that 20 is an appropriate value for a pointer to an integer? printf("%d",*p); Broken. What exactly do you think a pointer with the value 20 might point to? printf("%d",p); Broken. The size of a pointer to an integer need not be equal to sizeof(int). printf( "%p", (void*)p ); why can you explain Pure random chance, as far as the C standard is concerned. -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. Nov 15 '05 #3

 P: n/a venkatesh a écrit : int *p=20; This is kinda nonsense. What to you think it meant ? The portable way of initializing a pointer to an object are - NULL - The address of an object of the same type - the value returned by malloc() - the value returned by fopen() if the type is void* or FILE* and similar cases. But initialising a pointer with a plain integer is undefined by the language. Actually, it may work on a specific platform. It's called an implementation-dependent behaviour. -- C is a sharp tool Nov 15 '05 #4

 P: n/a yes, exactly what you wrote means: int* p; p = 20; Nov 15 '05 #5

 P: n/a vire wrote: yes, exactly what you wrote means: int* p; p = 20; Please read my .sig. Brian -- Please quote enough of the previous message for context. To do so from Google, click "show options" and use the Reply shown in the expanded header. Nov 15 '05 #6

 P: n/a Christopher Benson-Manica writes: venkatesh wrote: int *p=20; Broken. What makes you suspect that 20 is an appropriate value for a pointer to an integer? What's surprising is that his compiler thought it was appropriate. A compiler might allow assigning an integer value to a pointer as an extension, but if the code is compiled in strict mode (might be called "ansi" or "iso", depending on the compiler), the compiler is required to issue a diagnostic. [...] printf("%d",p); Broken. The size of a pointer to an integer need not be equal to sizeof(int). Size matters not. Using "%d" to print a pointer value invokes undefined behavior (though it will often do what you expect anyway). It can fail even if int and int* happen to have the same size. The correct way to print an int* value is: printf("%p", (void*)p); Also, the original code, if it doesn't blow up, will probably print the values adjacent to each other; you won't be able to tell where one ends and the other begins. Rather than int *p=20; printf("%d",*p); printf("%d",p); you might try this: int *p = (int*)20; printf("*p = %d\n", *p); printf("p = %p\n", (int*)p); Of course this could still invoke undefined behavior, since (int*)20 is unlikely to be a valid address. Here's a program that actually works: #include #include int main (void) { int *p = malloc(sizeof *p); if (p == NULL) { printf("malloc failed\n"); } else { *p = 20; printf("*p = %d\n", *p); printf("p = %p\n", (void*)p); } return 0; } -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 15 '05 #7

 P: n/a Keith Thompson wrote: The correct way to print an int* value is: printf("%p", (void*)p); (which I did mention, FWIW) Of course this could still invoke undefined behavior, since (int*)20 is unlikely to be a valid address. Is it not UB regardless, since 20 is not a value obtained from malloc()? -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. Nov 15 '05 #8

 P: n/a Emmanuel Delahaye writes: venkatesh a écrit : int *p=20; This is kinda nonsense. What to you think it meant ? The portable way of initializing a pointer to an object are - NULL - The address of an object of the same type - the value returned by malloc() - the value returned by fopen() if the type is void* or FILE* and similar cases. And 0 (or any 0-valued constant expression). But initialising a pointer with a plain integer is undefined by the language. Unless the integer is 0. Nov 15 '05 #9

 P: n/a Christopher Benson-Manica writes: Keith Thompson wrote: The correct way to print an int* value is: printf("%p", (void*)p); (which I did mention, FWIW) Ok. Of course this could still invoke undefined behavior, since (int*)20 is unlikely to be a valid address. Is it not UB regardless, since 20 is not a value obtained from malloc()? Valid pointers don't have to be obtained from malloc(). The conversion itself yields an implementation-defined result: An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation. with a footnote: The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment. If the result happens to be an invalid pointer, dereferencing it invokes undefined behavior. If the implementation happens to guarantee that 20 is a valid address for an int, the behavior of dereferencing (int*)20 is merely implementation-defined. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 15 '05 #10

 P: n/a Tim Rentsch a écrit :The portable way of initializing a pointer to an object are- NULL <...> And 0 (or any 0-valued constant expression). Unless the integer is 0. NULL was supposed to cover the case... -- C is a sharp tool Nov 15 '05 #11

 P: n/a Emmanuel Delahaye writes: Tim Rentsch a écrit :The portable way of initializing a pointer to an object are- NULL <...> And 0 (or any 0-valued constant expression). Unless the integer is 0. NULL was supposed to cover the case... I guessed that might have been the intention; however, NULL is not guaranteed to be 0, and typically in fact it isn't. Nov 15 '05 #12

 P: n/a On 2005-10-26, Tim Rentsch wrote: Emmanuel Delahaye writes: Tim Rentsch a écrit : >>The portable way of initializing a pointer to an object are >> >>- NULL <...> > And 0 (or any 0-valued constant expression). > Unless the integer is 0. NULL was supposed to cover the case... I guessed that might have been the intention; however, NULL is not guaranteed to be 0, and typically in fact it isn't. It's not guaranteed to be all-bits-zero, but that's not what he claimed. It might be ((void *)0) or something like that, but i very much doubt anyone has it as ((void *)0xdeadbeef), especially given that NULL _is_ guaranteed to become 0 when converted to an integer Nov 15 '05 #13

 P: n/a Jordan Abel writes: On 2005-10-26, Tim Rentsch wrote: [...] I guessed that might have been the intention; however, NULL is not guaranteed to be 0, and typically in fact it isn't. It's not guaranteed to be all-bits-zero, but that's not what he claimed. It might be ((void *)0) or something like that, but i very much doubt anyone has it as ((void *)0xdeadbeef), especially given that NULL _is_ guaranteed to become 0 when converted to an integer No, I don't believe it is. If NULL is defined as 0, then of course it's already of type int. But if NULL is defined as (void*)0, then it's an expression of type void*, and there's no guarantee that converting it to int will yield the value 0. The only specific guarantee is that a null pointer constant converted to a pointer type yields a null pointer, and that only applies at compilation time. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 15 '05 #14

 P: n/a On 2005-10-26, Keith Thompson wrote: Jordan Abel writes: On 2005-10-26, Tim Rentsch wrote: [...] I guessed that might have been the intention; however, NULL is not guaranteed to be 0, and typically in fact it isn't. It's not guaranteed to be all-bits-zero, but that's not what he claimed. It might be ((void *)0) or something like that, but i very much doubt anyone has it as ((void *)0xdeadbeef), especially given that NULL _is_ guaranteed to become 0 when converted to an integer No, I don't believe it is. If NULL is defined as 0, then of course it's already of type int. But if NULL is defined as (void*)0, then it's an expression of type void*, and there's no guarantee that converting it to int will yield the value 0. I could have sworn that there was a guarantee that null pointers (constant or otherwise) convert to zero how does if(p) work, then? if(p != 0) can be explained by the 0 being converted to a null pointer, and !p is defined as 0==p but i could have sworn the argument in a conditional had to be an integer type The only specific guarantee is that a null pointer constant converted to a pointer type yields a null pointer, and that only applies at compilation time. actually, though i could find nothing supporting my belief about conversions to integer, apparently (from my interpretation) conversions from any null pointer to any pointer type [at least, any that the original pointer type is allowed to be converted to - void pointer and pointer types with 'less strict alignment'] yield a null pointer - constant or otherwise. It doesn't actually say that, but you can get as far as "will compare equal [with the original null pointer]" from other statements, and it seems implied that any pointer that will compare equal with a null pointer is a null pointer. Nov 15 '05 #15

 P: n/a Jordan Abel writes: On 2005-10-26, Tim Rentsch wrote: Emmanuel Delahaye writes: Tim Rentsch a écrit : >>The portable way of initializing a pointer to an object are >> >>- NULL <...> > And 0 (or any 0-valued constant expression). > Unless the integer is 0. NULL was supposed to cover the case... I guessed that might have been the intention; however, NULL is not guaranteed to be 0, and typically in fact it isn't. It's not guaranteed to be all-bits-zero, but that's not what he claimed. It might be ((void *)0) or something like that, but i very much doubt anyone has it as ((void *)0xdeadbeef), especially given that NULL _is_ guaranteed to become 0 when converted to an integer I didn't say anything about all-bits-zero. NULL usually is something other than 0 (even if it compares equal to 0), but 0 always works in initializing a pointer variable, so I thought it should be mentioned in addition to mentioning NULL. Also using 0 rather than NULL can be done without having to #include anything. That's clearly a way that 0 and NULL are different. Nov 15 '05 #16

 P: n/a Jordan Abel wrote: I could have sworn that there was a guarantee that null pointers (constant or otherwise) convert to zero Nope. Constant zeroes convert to null pointers; the other way 'round is common, but not guaranteed. how does if(p) work, then? if(p != 0) can be explained by the 0 being converted to a null pointer, and !p is defined as 0==p but i could have sworn the argument in a conditional had to be an integer type You would have perjured yourself. "The controlling expression of an if statement shall have scalar type" is all the Standard has to say about it. Well, that, and that the path taken depends on whether said expression compares equal to 0. Richard Nov 15 '05 #17

 P: n/a Tim Rentsch wrote: I didn't say anything about all-bits-zero. NULL usually is something other than 0 (even if it compares equal to 0), but 0 always works in initializing a pointer variable, so I thought it should be mentioned in addition to mentioning NULL. Do you have some evidence for "usually something other than 0"? Brian Nov 15 '05 #18

 P: n/a "Default User" writes: Tim Rentsch wrote: I didn't say anything about all-bits-zero. NULL usually is something other than 0 (even if it compares equal to 0), but 0 always works in initializing a pointer variable, so I thought it should be mentioned in addition to mentioning NULL. Do you have some evidence for "usually something other than 0"? Only a personal informal survey. If someone has more extensive data to report, I'd be interested to hear about (whether it agrees with mine or not). Nov 15 '05 #19

 P: n/a Tim Rentsch wrote: "Default User" writes: Do you have some evidence for "usually something other than 0"? Only a personal informal survey. If someone has more extensive data to report, I'd be interested to hear about (whether it agrees with mine or not). My two data points are the VC++ 6.0 and gcc 3.3.1 on Solaris, which both give an all-bits-zero null pointer. Note that this doesn't have anything to do with the standard language at all. It's been my impression from previous discussion that some non 0 null pointers exist, but that they were in the minority. Brian Nov 15 '05 #20

 P: n/a "Default User" writes: Tim Rentsch wrote: "Default User" writes: Do you have some evidence for "usually something other than 0"? Only a personal informal survey. If someone has more extensive data to report, I'd be interested to hear about (whether it agrees with mine or not). My two data points are the VC++ 6.0 and gcc 3.3.1 on Solaris, which both give an all-bits-zero null pointer. Note that this doesn't have anything to do with the standard language at all. It's been my impression from previous discussion that some non 0 null pointers exist, but that they were in the minority. We're talking about two different things. My comment was about the definition of the NULL macro, whether it is, eg, #define NULL 0 or, eg, #define NULL (void*)0 Your comment is about the representation - eg, "all-bits-zero" - of a null pointer (whether or not it comes from NULL). I wasn't making any representations about the representation of a null pointer. Nov 15 '05 #21

 P: n/a On 2005-10-26, Tim Rentsch wrote: "Default User" writes: [...] We're talking about two different things. My comment was about the definition of the NULL macro, whether it is, eg, #define NULL 0 or, eg, #define NULL (void*)0 I'm thinking the latter would be better phrased as ((void *)0) .... because omission of the parentheses causes NULL not to group in expressions as though it were a single identifier, thus violating C90+ TC1 and C99. The text that says this is in subclause 7.1.2 and identically worded in both standards: Any definition of an object-like macro described in this clause shall expand to code that is fully protected by parentheses where necessary, so that it groups in an arbitrary expression as if it were a single identifier. (This was added to C90 in response to Defect Report 43: http://www.open-std.org/jtc1/sc22/wg...cs/dr_043.html and has been discussed in comp.std.c before: http://groups.google.com/group/comp....p.std.c&hl=en&) -- Nils R. Weller, Bremen (Germany) My real email address is ``nilsgnulinuxnl'' .... but I'm not speaking for the Software Libre Foundation! Nov 15 '05 #22

 P: n/a Tim Rentsch wrote: We're talking about two different things. My comment was about the definition of the NULL macro, whether it is, eg, #define NULL 0 or, eg, #define NULL (void*)0 Your comment is about the representation - eg, "all-bits-zero" - of a null pointer (whether or not it comes from NULL). I wasn't making any representations about the representation of a null pointer. I see. Most of the headers I've looked at tend to either define it as 0 or use #ifdefs to give 0 for C++ or (void *)0 for C. Brian Nov 15 '05 #23

 P: n/a Nils Weller writes: On 2005-10-26, Tim Rentsch wrote: "Default User" writes: [...] We're talking about two different things. My comment was about the definition of the NULL macro, whether it is, eg, #define NULL 0 or, eg, #define NULL (void*)0 I'm thinking the latter would be better phrased as ((void *)0) ... because omission of the parentheses causes NULL not to group in expressions as though it were a single identifier, thus violating C90+ TC1 and C99. The text that says this is in subclause 7.1.2 and identically worded in both standards: Any definition of an object-like macro described in this clause shall expand to code that is fully protected by parentheses where necessary, so that it groups in an arbitrary expression as if it were a single identifier. It was just an example. Any definition that results in a value other than integer 0 would serve the purpose of the example. There are definitions of NULL that use (void*)0 rather than ((void*)0). But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. Nov 15 '05 #24

 P: n/a On 2005-10-26, Tim Rentsch wrote: Nils Weller writes: On 2005-10-26, Tim Rentsch wrote: [...] > #define NULL (void*)0 I'm thinking the latter would be better phrased as ((void *)0) ... because omission of the parentheses causes NULL not to group in expressions as though it were a single identifier, thus violating C90+ TC1 and C99. [...] But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. True, but your definition only works with this hypothetical implementation that you speak of and violates the standards if applied to most if not all typical, real-world implementations today. So if we are after portability (which I think most c.l.c. readers are), why not use the portable definition in examples :-) (I don't mean to hijack and turn this thread into a debate about this irrelevant detail; I just thought it would be interesting to mention this.) -- Nils R. Weller, Bremen (Germany) My real email address is ``nilsgnulinuxnl'' .... but I'm not speaking for the Software Libre Foundation! Nov 15 '05 #25

 P: n/a Tim Rentsch writes: [...] But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. If the implementation plays tricks like that, it's not very meaningful to say that NULL is defined in any particular way. There might be something in some file that looks like a macro definition, but it's not really *the* definition of NULL. I'm not convinced that such tricks are legal anyway. Can you cite a clause of the standard that says they are? -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 15 '05 #26

 P: n/a Tim Rentsch wrote: But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. There's also a good argument for why this isn't such an attractive approach, namely that it involves merging the preprocessor with the compiler, or at least a good part of it. Design-wise, it makes sense to keep them separated -- even if they're integrated in one program. Actually, it's a tad worse, because it also means making the preprocessor cope with "special" behaviour in system headers. Coping with broken or weird headers to somehow squeeze compliance out of them (assuming compiler and C library are separate) is already something of a black art, so reducing transparency by shifting the behaviour into binaries (rather than using scripts that fix (copies of) the headers) isn't such a hot idea. S. Nov 15 '05 #27

 P: n/a Nils Weller writes: On 2005-10-26, Tim Rentsch wrote: Nils Weller writes: On 2005-10-26, Tim Rentsch wrote: [...] > #define NULL (void*)0 I'm thinking the latter would be better phrased as ((void *)0) ... because omission of the parentheses causes NULL not to group in expressions as though it were a single identifier, thus violating C90+ TC1 and C99. [...] But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. True, but your definition only works with this hypothetical implementation that you speak of and violates the standards if applied to most if not all typical, real-world implementations today. So if we are after portability (which I think most c.l.c. readers are), why not use the portable definition in examples :-) Portability?!?? I thought most posters in c.l.c were after opportunities to show off their knowledge of ISO C minutiae. Also it's important to have examples be right near the edge of the envelope of what the Standard allows, so newbies can learn from the ensuing debates. Aren't these rules covered in the FAQ? (ok, ok, just kidding!) Nov 15 '05 #28

 P: n/a Skarmander writes: Tim Rentsch wrote: But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. There's also a good argument for why this isn't such an attractive approach, namely that it involves merging the preprocessor with the compiler, or at least a good part of it. Design-wise, it makes sense to keep them separated -- even if they're integrated in one program. Oh, I never said the argument for using '(void*)0' without the outer parentheses was a *good* argument; only that there is an argument. Actually, it's a tad worse, because it also means making the preprocessor cope with "special" behaviour in system headers. Coping with broken or weird headers to somehow squeeze compliance out of them (assuming compiler and C library are separate) is already something of a black art, so reducing transparency by shifting the behaviour into binaries (rather than using scripts that fix (copies of) the headers) isn't such a hot idea. Apparently my message has been read by some people as advocating the #define line above as a good way to define NULL. I wasn't. My point was only about what's allowed, not what's good. Nov 15 '05 #29

 P: n/a Keith Thompson writes: Tim Rentsch writes: [...] But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. If the implementation plays tricks like that, it's not very meaningful to say that NULL is defined in any particular way. There might be something in some file that looks like a macro definition, but it's not really *the* definition of NULL. There is some merit in what you say. Depending on special purpose processing like this makes it difficult to talk about program elements with our usual vocabulary, because the meanings of the words have gotten rather slippery. However, I don't think it diminishes my basic point, which is that we can't conclude a priori that the #define line above "can't work". For example, suppose the system header file contained these lines: #pragma object_macro NULL ... #define NULL (void*)0 with the obvious meaning for the #pragma line. I think most people wouldn't be especially bothered by an implementation that defined NULL in this way; surprised perhaps, but not especially bothered. Furthmore, in some sense this definition reflects more directly what the Standard requires of NULL - namely, that it is an object macro, and that it produces a null pointer constant. To restate my basic point: we can't conclude a priori that a #define line #define NULL (void*)0 has problems; it's allowed, and it can be conformant. And I would now add: in ways that aren't too much of a stretch. I'm not convinced that such tricks are legal anyway. Can you cite a clause of the standard that says they are? Basically 7.1.2, especially paragraph 1. System headers don't have to be files in the ordinary sense, and the wording in the Standard says that the "contents [of the header] are made available by the #include preprocessing directive." The contents are "made available", but there don't seem to be any restrictions on how that's done, or what form the "contents" take. Also I think it's fairly commonly accepted that an implementation is allowed to treat system functions in special ways, eg, inline data movement for 'memcpy()'; I guess this freedom is generally allowed under the "as if" rule, which seems to apply equally to NULL as it does to memcpy(), etc. Nov 15 '05 #30

 P: n/a On 2005-10-26, Keith Thompson wrote: Tim Rentsch writes: [...] But to respond to the point, a system header file could include a definition #define NULL (void*)0 and the implementation still meet the requirements of C90+TC1 and C99; that could be done by having the compiler check whether a text sequence '(void*)0' arose as a result of expanding NULL, and whether the definition came from the system file, and if so treat the expansion as an atomic unit. An implementation is allowed to do this sort of thing for definitions in system header files. There's even an argument that says it's better to do this, since the Standard's definition of the term "null pointer constant" comprises '(void*)0' but not '((void*)0)'; however, I'm not trying to say that it's better, only that it's allowed and can be conformant. If the implementation plays tricks like that, it's not very meaningful to say that NULL is defined in any particular way. There might be something in some file that looks like a macro definition, but it's not really *the* definition of NULL. I'm not convinced that such tricks are legal anyway. Can you cite a clause of the standard that says they are? It's called the "as if" rule - I don't know where if anywhere it's spelled out in the standard, but it's used pretty much everywhere - a good explanation is in the rationale document section 2.1 standard header files aren't required to exist at all, either - the compiler could just know what each one means Nov 15 '05 #31

 P: n/a Tim Rentsch wrote: Apparently my message has been read by some people as advocating the #define line above as a good way to define NULL. I wasn't. My point was only about what's allowed, not what's good. "There's even an argument that says it's better to do this". Come on, that warrants a rebuttal. :-) I never claimed *you* thought it was a good idea, or that you were advocating it. Doesn't mean counterarguments weren't in order. A great many things are "allowed" that still need to be avoided. S. Nov 15 '05 #33

 P: n/a Skarmander writes: Tim Rentsch wrote: Apparently my message has been read by some people as advocating the #define line above as a good way to define NULL. I wasn't. My point was only about what's allowed, not what's good. "There's even an argument that says it's better to do this". Come on, that warrants a rebuttal. :-) I never claimed *you* thought it was a good idea, or that you were advocating it. Doesn't mean counterarguments weren't in order. A great many things are "allowed" that still need to be avoided. Does this mean you'd present a counterargument even if no one was advocating the argument? Nov 15 '05 #34

 P: n/a Tim Rentsch wrote: Skarmander writes:Tim Rentsch wrote:Apparently my message has been read by some people as advocatingthe #define line above as a good way to define NULL. I wasn't.My point was only about what's allowed, not what's good."There's even an argument that says it's better to do this". Come on,that warrants a rebuttal. :-)I never claimed *you* thought it was a good idea, or that you wereadvocating it. Doesn't mean counterarguments weren't in order. A greatmany things are "allowed" that still need to be avoided. Does this mean you'd present a counterargument even if no one was advocating the argument? Yes. I just did, didn't I? TR: "Here's an approach. I'm not saying it's a good approach, just that it's allowed." S: "And here's why it's not a good approach." What's wrong with this? I'm protecting the innocent. :-) S. Nov 15 '05 #35