|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Is it OK to dereference NULL pointers if the only thing you are doing
is storing them in a reference then comparing addresses to NULL again later, as in: === BEGIN EXAMPLE === Something g_something; const Something & getSomething () { if (condition) return g_something; else return *(const Something *)NULL; // <--- !!! } void function () { const Something &s = getSomething; if (&s == NULL) { // <--- !!! // ... } else { // ... } } === END EXAMPLE === Thanks, Jason |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
jason.cipriani@gmail.com writes:
> Is it OK to dereference NULL pointers if the only thing you are doing > is storing them in a reference then comparing addresses to NULL again > later, as in: Well, it or may not be legal. But, doing that is like dressing up like a Santa Claus and walking past a hungry bull. It's not advisable. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEABECAAYFAkh9WuoACgkQx9p3GYHlUOL0pwCfc7HdLKZK9k 5Y3kv4zHvgAPC/ 4AQAnRX+YJPQTD9kr3sgONXqjCwBkacQ =Ykj2 -----END PGP SIGNATURE----- |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
* jason.cipriani@gmail.com:
> Is it OK to dereference NULL pointers if the only thing you are doing > is storing them in a reference then comparing addresses to NULL again > later No. That incurs Undefined Behavior. Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Jul 15, 10:32 pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * jason.cipri...@gmail.com: > > > Is it OK to dereference NULL pointers if the only thing you are doing > > is storing them in a reference then comparing addresses to NULL again > > later > > No. > > That incurs Undefined Behavior. Then, if this is undefined: Something &ref = *(Something &)NULL; Doesn't that mean this also undefined? Something *ptr = NULL; Something &ref = *ptr; And if so, then that also means this is undefined, as the possibility exists for the pointer to be NULL? Something * function (); Something *ptr = function(); Something &ref = *ptr; And if that is undefined, is this the cleanest way to make sure nothing undefined happens? Something * function (); Something *ptr = function(); if (ptr) { Something &ref = *ptr; // ... } else { // error } Also, unrelated to references, just out of curiosity, does that mean statements like this are also undefined: Something *ptr = &(*(Something *)NULL); Thanks, Jason |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Jul 15, 10:49 pm, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote: > Then, if this is undefined: > > Something &ref = *(Something &)NULL; I'm sorry this should read: Something &ref = *(Something *)NULL; Jason |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
* jason.cipriani@gmail.com:
> On Jul 15, 10:32 pm, "Alf P. Steinbach" <al...@start.no> wrote: >> * jason.cipri...@gmail.com: >> >>> Is it OK to dereference NULL pointers if the only thing you are doing >>> is storing them in a reference then comparing addresses to NULL again >>> later >> No. >> >> That incurs Undefined Behavior. > > Then, if this is undefined: > > Something &ref = *(Something *)NULL; Yes. > Doesn't that mean this also undefined? > > Something *ptr = NULL; > Something &ref = *ptr; Yes. > And if so, then that also means this is undefined, as the possibility > exists for the pointer to be NULL? > > Something * function (); > Something *ptr = function(); > Something &ref = *ptr; Depends on whether the pointer actually can be 0. It's the actual dereferencing of a nullpointer that incurs Undefined Behavior. Not the potential. > And if that is undefined, is this the cleanest way to make sure > nothing undefined happens? > > Something * function (); > Something *ptr = function(); > if (ptr) { > Something &ref = *ptr; > // ... > } else { > // error > } Depends. Instead of a kludgy if-else construction I'd prefer to just 'return' or 'break' or 'throw' or 'abort' or whatever. Not cluttering normal case code with error processing. > Also, unrelated to references, just out of curiosity, does that mean > statements like this are also undefined: > > Something *ptr = &(*(Something *)NULL); Yes. There are some exceptions to incurring UB for dereferencing a nullpointer. The most important one is that any given compiler vendor can decide to give that a well-defined meaning at compile time for that compiler, and exploit that to implement various macros in the standard library. Another one is the context of a typeid call. Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Jul 15, 11:04 pm, "Alf P. Steinbach" <al...@start.no> wrote:
> Depends on whether the pointer actually can be 0. It's the actual dereferencing > of a nullpointer that incurs Undefined Behavior. Not the potential. Oh, I guess that makes sense. Thanks for the good response and explanation. Jason |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Jul 16, 5:04 am, "Alf P. Steinbach" <al...@start.no> wrote:
> There are some exceptions to incurring UB for dereferencing a > nullpointer. The most important one is that any given compiler > vendor can decide to give that a well-defined meaning at > compile time for that compiler, and exploit that to implement > various macros in the standard library. Another one is the > context of a typeid call. Hows that? Modulo vendor specific guarantees (of course), it's undefined behavior to dereference a null pointer in code that actually gets executed. Something like sizeof( *p ) is fine, even if p is a null pointer. But typeid normally requires execution, e.g.: typeid( *p ) is undefined behavior if p is a null pointer (and the pointed to object has a polymorphic type, but then, that's the usual reason for using typeid). -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
* James Kanze:
> On Jul 16, 5:04 am, "Alf P. Steinbach" <al...@start.no> wrote: > >> There are some exceptions to incurring UB for dereferencing a >> nullpointer. The most important one is that any given compiler >> vendor can decide to give that a well-defined meaning at >> compile time for that compiler, and exploit that to implement >> various macros in the standard library. Another one is the >> context of a typeid call. > > Hows that? > > Modulo vendor specific guarantees (of course), it's undefined > behavior to dereference a null pointer in code that actually > gets executed. Something like sizeof( *p ) is fine, even if p > is a null pointer. But typeid normally requires execution, > e.g.: typeid( *p ) is undefined behavior if p is a null pointer > (and the pointed to object has a polymorphic type, but then, > that's the usual reason for using typeid). I'm sorry, that's incorrect. §5.2.8/2, typeid guarantees to throw a std::bad_typeid exception if you give it an lvalue formed by dereferencing a nullpointer to polymorphic type. So we're out of UB-land and into guaranteed exception-land. :-) Cheers, - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
On 2008-07-15 23:04:29 -0400, "Alf P. Steinbach" <alfps@start.no> said:
> > There are some exceptions to incurring UB for dereferencing a > nullpointer. The most important one is that any given compiler vendor > can decide to give that a well-defined meaning at compile time for that > compiler, and exploit that to implement various macros in the standard > library. That is not an exception to the meaning of undefined behavior. The language definition says that certain things result in undefined behavior, and that means that the language definition doesn't tell you what those things do. The possiblity that a particular compiler vendor makes some of those things well defined doesnt change the fact that the language definition doesn't impose requirements. The behavior is still undefined. -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book) |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
On Jul 16, 1:28 pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * James Kanze: > > On Jul 16, 5:04 am, "Alf P. Steinbach" <al...@start.no> wrote: > >> There are some exceptions to incurring UB for dereferencing a > >> nullpointer. The most important one is that any given compiler > >> vendor can decide to give that a well-defined meaning at > >> compile time for that compiler, and exploit that to implement > >> various macros in the standard library. Another one is the > >> context of a typeid call. > > Hows that? > > Modulo vendor specific guarantees (of course), it's undefined > > behavior to dereference a null pointer in code that actually > > gets executed. Something like sizeof( *p ) is fine, even if p > > is a null pointer. But typeid normally requires execution, > > e.g.: typeid( *p ) is undefined behavior if p is a null pointer > > (and the pointed to object has a polymorphic type, but then, > > that's the usual reason for using typeid). > I'm sorry, that's incorrect. §5.2.8/2, typeid guarantees to > throw a std::bad_typeid exception if you give it an lvalue > formed by dereferencing a nullpointer to polymorphic type. So > we're out of UB-land and into guaranteed exception-land. :-) Interesting. A bit strange, but who's to complain. Anything which reduces undefined behavior is good. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
* Pete Becker:
> On 2008-07-15 23:04:29 -0400, "Alf P. Steinbach" <alfps@start.no> said: > >> >> There are some exceptions to incurring UB for dereferencing a >> nullpointer. The most important one is that any given compiler vendor >> can decide to give that a well-defined meaning at compile time for >> that compiler, and exploit that to implement various macros in the >> standard library. > > That is not an exception to the meaning of undefined behavior. The > language definition says that certain things result in undefined > behavior, and that means that the language definition doesn't tell you > what those things do. The possiblity that a particular compiler vendor > makes some of those things well defined doesnt change the fact that the > language definition doesn't impose requirements. Agreed, up till this point. I was talking about incurring UB and you're talking about the meaning of UB. > The behavior is still undefined. No, of course it isn't: it's then only undefined with respect to the standard. Cheers, - Alf (all's relative these days) -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
On 2008-07-16 17:36:59 -0400, "Alf P. Steinbach" <alfps@start.no> said:
> * Pete Becker: >> On 2008-07-15 23:04:29 -0400, "Alf P. Steinbach" <alfps@start.no> said: >> >>> >>> There are some exceptions to incurring UB for dereferencing a >>> nullpointer. The most important one is that any given compiler vendor >>> can decide to give that a well-defined meaning at compile time for that >>> compiler, and exploit that to implement various macros in the standard >>> library. >> >> That is not an exception to the meaning of undefined behavior. The >> language definition says that certain things result in undefined >> behavior, and that means that the language definition doesn't tell you >> what those things do. The possiblity that a particular compiler vendor >> makes some of those things well defined doesnt change the fact that the >> language definition doesn't impose requirements. > > Agreed, up till this point. I was talking about incurring UB and > you're talking about the meaning of UB. I don't know what "incurring UB" means. The standard simply says that the behavior of the program is undefined, not that anyting incurs anything. > > >> The behavior is still undefined. > > No, of course it isn't: it's then only undefined with respect to the standard. > It may do what some implementor says it does. That doesn't change the fact that it's undefined behavior. If you're using the term "undefined behavior" to mean something other than what the standard says it means, you need to say so. -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book) |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
* Pete Becker:
> On 2008-07-16 17:36:59 -0400, "Alf P. Steinbach" <alfps@start.no> said: > >> * Pete Becker: >>> On 2008-07-15 23:04:29 -0400, "Alf P. Steinbach" <alfps@start.no> said: >>> >>>> >>>> There are some exceptions to incurring UB for dereferencing a >>>> nullpointer. The most important one is that any given compiler >>>> vendor can decide to give that a well-defined meaning at compile >>>> time for that compiler, and exploit that to implement various macros >>>> in the standard library. >>> >>> That is not an exception to the meaning of undefined behavior. The >>> language definition says that certain things result in undefined >>> behavior, and that means that the language definition doesn't tell >>> you what those things do. The possiblity that a particular compiler >>> vendor makes some of those things well defined doesnt change the fact >>> that the language definition doesn't impose requirements. >> >> Agreed, up till this point. I was talking about incurring UB and >> you're talking about the meaning of UB. > > I don't know what "incurring UB" means. The standard simply says that > the behavior of the program is undefined, not that anyting incurs anything. I'll answer in kind, at that level. It's not "the program" (a static entity) that has undefined behavior, it's a given executing instance of the program which has dereferenced a nullpointer. Up to the point where the nullpointer was dereferenced, that instance had, presumably, well-defined behavior. It incurs undefined behavior by the dynamic action of dereferencing a nullpointer. For the meaning of "incur", se e.g. <url: http://www.tfd.com/incurs>. >>> The behavior is still undefined. >> >> No, of course it isn't: it's then only undefined with respect to the >> standard. >> > > It may do what some implementor says it does. That doesn't change the > fact that it's undefined behavior. If you're using the term "undefined > behavior" to mean something other than what the standard says it means, > you need to say so. The implication that I've used the term "undefined behavior" with some other meaning, is a false and misleading one. Apart from that, I think there's not much wrong with this latest paragraph. You could have added "with respect to the standard" at the end of the second sentence, to the slow-witted reader. But then that's implied by context and would simply be annoying to the more intelligent. So the question is, as always, one of context: who are we writing for. Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? |
|
![]() |
| Outils de la discussion | |
|
|