Guess what I found in MFC's source code?
-
Hmmmm, I think overlapping is still the wrong term. Maybe "nested function calls", where a function calls a function that calls a function, etc., etc.? I think that's the nature of C++, and in most real-world apps that perform a useful set of actions, you simply won't be able to avoid it in your own code. ------- sig starts "I've heard some drivers saying, 'We're going too fast here...'. If you're not here to race, go the hell home - don't come here and grumble about going too fast. Why don't you tie a kerosene rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
John Simmons / outlaw programmer wrote: I think that's the nature of C++, and in most real-world apps that perform a useful set of actions, you simply won't be able to avoid it in your own code. what do you mean ??? i was thinking of code that microsoft library programmers that is awful, and that could be other way. look at this :
<vector> line 234:
//...
{for (; _F != _L; ++_P, ++_F)
allocator.construct(_P, *_F);
return (_P); }
//...if i had to write such code myself, i would give explicit names to the variables, unpack the commands, and of course, i would have written such code in a cpp (not a header)....
TOXCCT >>> GEII power
-
class autoclose { HFILE * handle; autoclose(HFILE & hHandle) : handle(&hHandle) {} ~autoclose() {CloseHandle(*handle);} }; myroutine() { HFILE hFile = NULL; autoclose ac(hFile); if((hFile = CreateFile(...)) == NULL) return; ReadFile(...); if(dwRead == 0) return; WriteFile(...); if(dwWritten == 0) return; ... } Drinking In The Sun Forgot Password?
Nice, but there are many different handles which must be closed in different ways. Ej: File Handles (HFILE), C-Files (FILE*), mallocs and news, etc. I've one encountered this problem with a cryptographyc library, where each single object had to be closed with a different function. Developing an autoclose for each object can result even more confusing than using goto. What's more, if you are going to use these handles in other places/programms, I simply prefer to envelope it in a class, where you can add other functionality.
-
Actually you could call
CloseHandle(hFile);
and put a return at the end of routine.myroutine()
{ HFILE hFile = NULL;
if((hFile = CreateFile(...)) == NULL)
{
CloseHandle(hFile);
return;
}
ReadFile(...);
if(dwRead == 0)
{
CloseHandle(hFile);
return;
}
WriteFile(...);
if(dwWritten == 0)
{
CloseHandle(hFile);
return;
}
...
}Now rewrite it so you're acquiring more, and more, and more resources, of different types. Before each
return
statement, you have to clean them all up all the resources you acquired, so your return blocks grow, and grow, and grow. It's a lot easier to assign a return value to a variable and jump to a cleanup block with agoto
. As for using the Resource Acquisition Is Initialisation pattern: MFC 6 still supports the oldsetjmp
/longjmp
-based TRY/CATCH macros, which in a traditional environment (when you haven't included setjmpex.h) doesn't run your destructors if youlongjmp
out of a block. The MFC 6 code-base is therefore defensively coded in case this occurs - explicitly freeing resources. I'm very familiar with this because I mainly code for Pocket PC, where there is no C++ exception handling, and MFC uses the old technique (warning! it still throwsCMemoryException
usinglongjmp
ifnew
fails). MFC 7 doesn't support thesetjmp
/longjmp
scheme (if you look inafx.h
, you'll see that defining_AFX_OLD_EXCEPTIONS
will cause an error). However, I'd still expect to see a lot of the old codebase present - if it ain't broke, etc - so you'll see a number of gotos in MFC 7, too. Stability. What an interesting concept. -- Chris Maunder -
I was just debugging an MFC program and surprise, surprise there is a Goto statement insinde wincore.cpp at line 2438: goto LReturnTrue; Hmmm...makes you wonder...;P Rob
Man and hear I am thinking you found something coll like Bill Gates Plans for world Domination hidden within comment lines ;P Discovery consist of seeing what everybody has seen and thinking what nobody has thought -- Albert Szent-Györgyi Name the greatest of all the inventors: accident --Mark Twain
-
John Simmons / outlaw programmer wrote: I think that's the nature of C++, and in most real-world apps that perform a useful set of actions, you simply won't be able to avoid it in your own code. what do you mean ??? i was thinking of code that microsoft library programmers that is awful, and that could be other way. look at this :
<vector> line 234:
//...
{for (; _F != _L; ++_P, ++_F)
allocator.construct(_P, *_F);
return (_P); }
//...if i had to write such code myself, i would give explicit names to the variables, unpack the commands, and of course, i would have written such code in a cpp (not a header)....
TOXCCT >>> GEII power
toxcct wrote: i would have written such code in a cpp (not a header).... I'm not sure about Microsoft's compiler but as a general rule template classes must be implemented inside header files so the compiler can generate the code for each of the types they're declared with. Regards, Alvaro
Give a man a fish, he owes you one fish. Teach a man to fish, you give up your monopoly on fisheries.
-
toxcct wrote: i would have written such code in a cpp (not a header).... I'm not sure about Microsoft's compiler but as a general rule template classes must be implemented inside header files so the compiler can generate the code for each of the types they're declared with. Regards, Alvaro
Give a man a fish, he owes you one fish. Teach a man to fish, you give up your monopoly on fisheries.
heinnnnn ??? where have you read that ? can you prove this ? header are not for implementation code. we usually put inside them the declarations, the constants sometimes, the prototypes, but no executable code. i'm waiting for your response with interest !
TOXCCT >>> GEII power
-
Maxwell Chen wrote: goto has its specific position to serve. I believe goto has one valid use: when there is a common clean up at the end of a routine (closing handles) and several possible errors cause early exit and the handles must still be closed.
myroutine()
{
HFILE hFile = NULL;if((hFile = CreateFile(...)) == NULL) goto sub\_exit; ReadFile(...); if(dwRead == 0) goto sub\_exit; WriteFile(...); if(dwWritten == 0) goto sub\_exit; ... sub\_exit: CloseHandle(hFile);
}
Ok, now there are try/finally blocks, but I think this is a valid use for gotos. Forget about undeclared variables and compilation errors! :) -- LuisR ___________ Luis Alonso Ramos Chihuahua, Mexico www.luisalonsoramos.com
This is the approached supported by the book Code Complete, Funny enough writen by Microsoft!
-
I was just debugging an MFC program and surprise, surprise there is a Goto statement insinde wincore.cpp at line 2438: goto LReturnTrue; Hmmm...makes you wonder...;P Rob
-
John Simmons / outlaw programmer wrote: I think that's the nature of C++, and in most real-world apps that perform a useful set of actions, you simply won't be able to avoid it in your own code. what do you mean ??? i was thinking of code that microsoft library programmers that is awful, and that could be other way. look at this :
<vector> line 234:
//...
{for (; _F != _L; ++_P, ++_F)
allocator.construct(_P, *_F);
return (_P); }
//...if i had to write such code myself, i would give explicit names to the variables, unpack the commands, and of course, i would have written such code in a cpp (not a header)....
TOXCCT >>> GEII power
1st, the code you refer to is not part of MFC, this is the implementation of standard C++ library that comes with VC. 2nd, these are templates. Declaration and definition of template classes should completely be in header files to be visible to compiler in producing concrete types (instantiation). 3rd, this is not even wrote by Microsoft - it was written by P.J. Plauger (and sold to Microsoft). I agree it could easily won some prizes on "obfuscated C++" contest :-D
-
I was just debugging an MFC program and surprise, surprise there is a Goto statement insinde wincore.cpp at line 2438: goto LReturnTrue; Hmmm...makes you wonder...;P Rob
goto
has been the subject of a lot of debute, but the only reasonable point is that some say usinggoto
is just the signs of a bad implementation. The jump agoto
statement uses is really no different that the jumps used for conditionals and switches. I really don't see any valid argument about not using them.Microsoft MVP, Visual C# My Articles
-
goto
has been the subject of a lot of debute, but the only reasonable point is that some say usinggoto
is just the signs of a bad implementation. The jump agoto
statement uses is really no different that the jumps used for conditionals and switches. I really don't see any valid argument about not using them.Microsoft MVP, Visual C# My Articles
-
1st, the code you refer to is not part of MFC, this is the implementation of standard C++ library that comes with VC. 2nd, these are templates. Declaration and definition of template classes should completely be in header files to be visible to compiler in producing concrete types (instantiation). 3rd, this is not even wrote by Microsoft - it was written by P.J. Plauger (and sold to Microsoft). I agree it could easily won some prizes on "obfuscated C++" contest :-D
i found this in "The C++ Language" from Bjarne Stroustrup, Chapter 13.7 : Organisation of the source code. (please appology mu english and my poor abilities in the translation (i've got the book, but in french). [...] In fact, the definition of out(), and all the declarations it depends on, are included into several compilation units. The compiler must generate the code (uniquely) when necessary, and optimize the reading multiple definitions process. In this strategy, the template functions are treatd exactly as inline functions. In this case, an obvious problem appears. Every element depending on the definition of out() is added into each file that use this function. Quantity of information that has to be treatd by the compiler is so considerably grown up. Another problem reside in the fact that users can become dependant on some declarations included uniquely for the out definition. This danger can be minimized while using namespaces, avoiding coding macros and reducing quantity of informations so included. The strategy of separate the compilation is the logical solution to this reasoning : if the template definition don't appear in the user code, none of its dependances can affect this code. This is why we split here the original out.c file into the following two :
// out.h
template<class T> void out (const T&);// out.c
#include <iostream>
#include "out.h"
export template<class T> void out (const T& t) { std::cerr << t; }the out.c file now contain all the requiered information to define out(), and out.h only contain useful information to call it. A user will only have to include the declaration (interface) :
#include "out.h"
[...]. i let you notice that the definition and the implementation are well splited !!!
TOXCCT >>> GEII power
-
Yes, and besides that, my version has only one exit point AND it closes the handle (if the handle was created). So you see, the short way, and more importantly the *exotic* way, are almost always less desireable than the *right* way. And before anyone becomes pedant, I am aware there are several "right" ways, but my point is that some ways are more right than others, and I will always stress maintainability over short/exotic. I hope I have been sufficiently pellucid, even for those who's most prominent physical feature is their single eyebrow which is more-or-less centered on their sloping foreheads. Thanks for playing our game. You may now grunt amongst yourselves. ------- sig starts "I've heard some drivers saying, 'We're going too fast here...'. If you're not here to race, go the hell home - don't come here and grumble about going too fast. Why don't you tie a kerosene rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
-
I was just debugging an MFC program and surprise, surprise there is a Goto statement insinde wincore.cpp at line 2438: goto LReturnTrue; Hmmm...makes you wonder...;P Rob
I personally seldom use a Goto, but for those times when it makes sense, I am glad it is there. This one one of the reasons I did not like Java when it first became popular, since they were telling me I "could not" use a goto if I wish. Of course, I also did not like that they made no provisions for enums. It surely could not have been that hard to implement, but they figured they knew best :confused: It was funny how people would attack the poor little Goto, saying it made code hard to follow and led to spaghetti code while at the same time, these great thinkers would abuse classes is such a way that you would welcome pasta ;) As you can tell, you have touched a religous issue :) Rocky <>< www.HintsAndTips.com www.GotTheAnswerToSpam.com
-
goto
has been the subject of a lot of debute, but the only reasonable point is that some say usinggoto
is just the signs of a bad implementation. The jump agoto
statement uses is really no different that the jumps used for conditionals and switches. I really don't see any valid argument about not using them.Microsoft MVP, Visual C# My Articles
-
That's misleading code. When someone sees a "do" they're expecting an honest-to-god loop. I would do it this way:
error myroutine()
{
HFILE hFile = NULL;
error = success;
if ((hFile = CreateFile(...)))
{
ReadFile(...);
if (dwRead)
{
WriteFile(...);
if (!dwWritten)
{
error = write;
}
}
else
{
error = read;
}
CloseHandle(hFile);
}
else
{
error = create;
}
return error;
}No goto's, no fake loops, the calling function can always programatically respond to the "error" reported by the function, and it's more maintainable by new employees. I've never seen a valid reason to ghave goto's in a c++ function, and I've been doing C++ for 14 years. ------- sig starts "I've heard some drivers saying, 'We're going too fast here...'. If you're not here to race, go the hell home - don't come here and grumble about going too fast. Why don't you tie a kerosene rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
Personally, I use the fake loops often BUT I always include a warning that it IS a fake loop. I find it to be helpful for scoping objects and minimizing indentation. I view it as a personal preference and I prefer that to using gotos which I have also managed to avoid for a long, long time. __________________________________________ a two cent stamp short of going postal.
-
I was just debugging an MFC program and surprise, surprise there is a Goto statement insinde wincore.cpp at line 2438: goto LReturnTrue; Hmmm...makes you wonder...;P Rob
Every if is a goto, every for, while and do. The ?: operator is, function calls are, and returns are gotos to an adress that where picked up at a crowded plaza. try going without goto, and you will arrive nowhere. ;P
Flirt harder, I'm a Coder
mlog || Agile Programming | doxygen -
I personally seldom use a Goto, but for those times when it makes sense, I am glad it is there. This one one of the reasons I did not like Java when it first became popular, since they were telling me I "could not" use a goto if I wish. Of course, I also did not like that they made no provisions for enums. It surely could not have been that hard to implement, but they figured they knew best :confused: It was funny how people would attack the poor little Goto, saying it made code hard to follow and led to spaghetti code while at the same time, these great thinkers would abuse classes is such a way that you would welcome pasta ;) As you can tell, you have touched a religous issue :) Rocky <>< www.HintsAndTips.com www.GotTheAnswerToSpam.com
Rocky Moore wrote: I personally seldom use a Goto, but for those times when it makes sense, I am glad it is there. This one one of the reasons I did not like Java when it first became popular, since they were telling me I "could not" use a goto if I wish. Of course, I also did not like that they made no provisions for enums. It surely could not have been that hard to implement, but they figured they knew best I think the Java creators were striving to achieve the complete opposite of C++: simplicity. Everything is either a class type or a primitive type (char, int, float, double, byte). They also figured
goto
s are so seldomly the superior route that not having them would force people to write proper code (without them). In other words, get rid of the gun so that people who don't know how and when to use it properly don't get any funny ideas. :-) One thing I think Java should have had was Properties. They don't add much to the complexity and improve readability a lot:int s = obj.Something;
vs.int s = obj.getSomething();
Regards, Alvaro
Give a man a fish, he owes you one fish. Teach a man to fish, you give up your monopoly on fisheries.
-
Rocky Moore wrote: I personally seldom use a Goto, but for those times when it makes sense, I am glad it is there. This one one of the reasons I did not like Java when it first became popular, since they were telling me I "could not" use a goto if I wish. Of course, I also did not like that they made no provisions for enums. It surely could not have been that hard to implement, but they figured they knew best I think the Java creators were striving to achieve the complete opposite of C++: simplicity. Everything is either a class type or a primitive type (char, int, float, double, byte). They also figured
goto
s are so seldomly the superior route that not having them would force people to write proper code (without them). In other words, get rid of the gun so that people who don't know how and when to use it properly don't get any funny ideas. :-) One thing I think Java should have had was Properties. They don't add much to the complexity and improve readability a lot:int s = obj.Something;
vs.int s = obj.getSomething();
Regards, Alvaro
Give a man a fish, he owes you one fish. Teach a man to fish, you give up your monopoly on fisheries.
Alvaro Mendez wrote: simplicity. Code with gotos is no less simplistic. In some code it can even add to the readabilty. Alvaro Mendez wrote: force people to write proper code (without them). In other words, get rid of the gun so that people who don't know how and when to use it properly don't get any funny ideas. That is just the point, who is it that told them they possessed all knowledge and only they new what "proper code" is? Just like with guns, we should still be allowed to possess and use them regardless that some people abuse them. Alvaro Mendez wrote: One thing I think Java should have had was Properties. They don't add much to the complexity and improve readability a lot: Yep, properties can be handy. So can enums and gotos :) Rocky <>< www.HintsAndTips.com www.GotTheAnswerToSpam.com
-
You could also write fo in such a way that it returns to a calling function for the more code part instead of having "more code" itself. Voila - no goto needed. ------- sig starts "I've heard some drivers saying, 'We're going too fast here...'. If you're not here to race, go the hell home - don't come here and grumble about going too fast. Why don't you tie a kerosene rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
Heh, you're right :-O "After all it's just text at the end of the day. - Colin Davies "For example, when a VB programmer comes to my house, they may say 'does your pool need cleaning, sir ?' " - Christian Graus