![]() |
|
|
Welcome to the { mindfrost82.com } forums. You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today! If you have any problems with the registration process or your account login, please contact contact us. |
|
|||||||
![]() |
|
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
|
|||
|
Difference between "unspecified behaviour" and "undefined behaviour"
Hi,
I have been trying to understand the differences between these two but I get confused in many situations. E.g. should the code below have undefined behaviour or unspecified behaviour. N2691 ($12.4/13 says that in such a situation the behaviour is undefined), though according to me it should be "unspecified" (behavior, for a well-formed program construct and correct data, that depends on the implementation....) class A{ public: A(){cout << "1";} ~A(){delete this;} }; int main(){ A*ptr = new A; delete ptr; } Please guide me on this. Dabs. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
rkldabs@gmail.com wrote:
> Hi, > > I have been trying to understand the differences between these two > but I get confused in many situations. Unspecified means that we know what the behaviour could be, usually a small set of alternatives, but in a particular case the standard doesn't specify which one. An example is a boolean function, which we know will always return either true or false. In some cases, like when comparing pointers into different containers, p < q will obviously return either true or false but we don't know which one. With undefined behaviour, all bets are off. There are no requirements at all. You also have "implementation defined" behaviour, which is similar to unspecified, in that there are a set of possible results, but an implementation must document which outcome it chooses. > > E.g. should the code below have undefined behaviour or unspecified > behaviour. N2691 ($12.4/13 says that in such a situation the > behaviour is undefined), though according to me it should be > "unspecified" (behavior, for a well-formed program construct and > correct data, that depends on the implementation....) > > class A{ > public: > A(){cout << "1";} > ~A(){delete this;} > }; > int main(){ > A*ptr = new A; > delete ptr; > } > This is totally different, in that deleting the pointer will invoke the destructor of A, which will again delete the pointer, which will invoke the destructor again, which will etc... Bo Persson -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
rkldabs@gmail.com wrote:
> Hi, > > I have been trying to understand the differences between these two but > I get confused in many situations. Unspecified behaviour is simply the case where the program is allowed to do any one of a (small) selection of possibilities and the compiler is not even required to select the same choice each time the code is executed (it is entirely permitted to make the choice based on the pahse of the moon or even pure whimsy) For example: int f(); int g(); int main(){ int i = f() + g(); } It is unspecified as to whether f or g is executed first (though currently they may not be executed in parallel -- and yes, it is quite possible to define f and g in such a way that the result used to initialise i will be independent of the order of evaluation, whilst an attempt to execute f and g concurrently will result in undefined behaviour) Undefined behaviour is a completely different kettle of fish. It is where the C++ Standard has nothing to say about the result and the side effects of trying to execute the code. For example: int main(){ int i; i++; } The C++ Standard has nothing to say about what the consequence will be of attempting to increment an uninitialised int value. > > E.g. should the code below have undefined behaviour or unspecified > behaviour. N2691 ($12.4/13 says that in such a situation the behaviour > is undefined), though according to me it should be > "unspecified" (behavior, for a well-formed program construct and > correct data, that depends on the implementation....) > > class A{ > public: > A(){cout << "1";} > ~A(){delete this;} Think carefully about what will happen when you attempt to execute this code. delete first calls the dtor for the object and then releases the dynamically provided base memory. So writing 'delete this' into the dtor for a type results in an infinite recursion. 'delete this' has a place in C++ but not in a dtor and not for a type that could ever be constructed on the stack. > }; > int main(){ > A*ptr = new A; > delete ptr; > } > > Please guide me on this. Just think what will happen and you do not need guidance. Just remember that unspecified behaviour allows the compiler to make (an undocumented) choice, undefined behaviour allows the compiler to create code that will reformat your hard-drive. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
On 5 août, 16:13, rkld...@gmail.com wrote:
> should the code below have undefined behaviour or unspecified > behaviour. > > class A{ > public: > A(){cout << "1";} > ~A(){delete this;}}; > > int main(){ > A*ptr = new A; > delete ptr; > > } To me, that's obviously undefined. You call the destructor twice. You free the memory twice. Only one of the two is required for undefined behaviour. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
rkldabs@gmail.com writes:
> I have been trying to understand the differences between these two but > I get confused in many situations. > > E.g. should the code below have undefined behaviour or unspecified > behaviour. N2691 ($12.4/13 says that in such a situation the behaviour > is undefined), though according to me it should be > "unspecified" (behavior, for a well-formed program construct and > correct data, that depends on the implementation....) > > class A{ > public: > A(){cout << "1";} > ~A(){delete this;} > }; > int main(){ > A*ptr = new A; > delete ptr; > } Undefined behavior. The object refered to by ptr is deleted twice. Unspecified behavior means that there is a set of defined behaviors of which one element is picked by the implementation. E.g. int f1(); int f2(); void g(int,int); int main() { g(f1(),f2()); } It is unspecified whether f1 or f2 is invoked first, but the program does't have undefined behavior (unless f1, f2 or g cause it). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
> Think carefully about what will happen when you attempt to execute this
> code. delete first calls the dtor for the object and then releases the > dynamically provided base memory. So writing 'delete this' into the dtor > for a type results in an infinite recursion. > > 'delete this' has a place in C++ but not in a dtor and not for a type > that could ever be constructed on the stack. Hi, as I understand both you and Persson have indicated that the above code causes infinite recursion. I would say that this means that the code has a pretty well defined behavior. Is there a platform/ architecture/scenario where this will not cause infinite recursion? If not, then isn't the behaviour of such code clear and crisp (i.e. causes infinite recursion) Regards, Dabs. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
Thomas Maeder wrote:
> rkldabs@gmail.com writes: > >> I have been trying to understand the differences between these two but >> I get confused in many situations. >> >> E.g. should the code below have undefined behaviour or unspecified >> behaviour. N2691 ($12.4/13 says that in such a situation the behaviour >> is undefined), though according to me it should be >> "unspecified" (behavior, for a well-formed program construct and >> correct data, that depends on the implementation....) >> >> class A{ >> public: >> A(){cout << "1";} >> ~A(){delete this;} >> }; >> int main(){ >> A*ptr = new A; >> delete ptr; >> } > > Undefined behavior. The object refered to by ptr is deleted twice. No it isn't. The delete ptr; expression calls ~A() which executes 'delete this' which in turn executes 'this->~A()' which now executes this->~A() ad nauseam. You must never ever write 'delete this' in a dtor because it results in a recursive call of the dtor. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
On 2008-08-06 04:20:50 -0400, rkldabs@gmail.com said:
>> Think carefully about what will happen when you attempt to execute this >> code. delete first calls the dtor for the object and then releases the >> dynamically provided base memory. So writing 'delete this' into the dtor >> for a type results in an infinite recursion. >> >> 'delete this' has a place in C++ but not in a dtor and not for a type >> that could ever be constructed on the stack. > > Hi, as I understand both you and Persson have indicated that the above > code causes infinite recursion. I would say that this means that the > code has a pretty well defined behavior. Is there a platform/ > architecture/scenario where this will not cause infinite recursion? If > not, then isn't the behaviour of such code clear and crisp (i.e. > causes infinite recursion) > The language defiinition is, ultimately, about visible behavior. Infinite recursion is not visible behavior. What happens when infinite recursion exhausts system resources is, and the language definition doesn't tell you what happens in that case. Most likely the program will crash, which is a typical symptom of undefined behavior. -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book) [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
rkldabs@gmail.com wrote:
>> Think carefully about what will happen when you attempt to execute this >> code. delete first calls the dtor for the object and then releases the >> dynamically provided base memory. So writing 'delete this' into the dtor >> for a type results in an infinite recursion. >> >> 'delete this' has a place in C++ but not in a dtor and not for a type >> that could ever be constructed on the stack. > > Hi, as I understand both you and Persson have indicated that the above > code causes infinite recursion. I would say that this means that the > code has a pretty well defined behavior. Is there a platform/ > architecture/scenario where this will not cause infinite recursion? If > not, then isn't the behaviour of such code clear and crisp (i.e. > causes infinite recursion) I would rather say, on most platforms it will not cause infinite recursion. The program will run out of stack, and the operating system will kill it, so the recursion is definitely finite. (-; Especially in the case of stack-overrun, I've seen many things happen: Inability to use the computer any more because it started swapping, stopping it down to a crawl, killing other random processes to get more memory for the stack, etc... So, yes, definitely undefined, and the consequences are typically not pleasant. So long, Thomas -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|||
|
Re: Difference between "unspecified behaviour" and "undefined behaviour"
> The language defiinition is, ultimately, about visible behavior.
> Infinite recursion is not visible behavior. What happens when infinite > recursion exhausts system resources is, and the language definition > doesn't tell you what happens in that case. Most likely the program > will crash, which is a typical symptom of undefined behavior. Thanks for all the valuable insights. Now the question that comes to my mind is regarding the order of passing arguments to functions. I think the choices are limited a) left to right b) right to left So going by what I have understood from the responses, the order of passing arguments to C++ functions is unspecified (limited set of options). Is this correct? However referring the link "http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=302" The very first line says "Standard C and C++ don’t define explicit calling conventions for functions.". I think this means "undefined" rather than "unspecified". I vaguely recollect documentation somewhere which said that the order of passing arguments to functions is "implementation defined". So here again I get confused.."unspecified", "undefined", "implementation defined"... -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
![]() |
|
| Thread Tools | Search this Thread |
| Display Modes | |
|
|