RES: Strange problem with VC++ compiler because of goto

Try rename your file to .CPP

Here I got the problem as .CPP and not as .C

s,

Fernando Roberto da Silva

DriverEntry Kernel Development

http://www.driverentry.com.br


De: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] Em nome de Prokash Sinha
Enviada em: quinta-feira, 17 de maio de 2007 11:09
Para: Windows System Software Devs Interest List
Assunto: Re: [ntdev] Strange problem with VC++ compiler because of goto

Raja,

I just took your code ( as is cut and paste), created a console app
using vc6 ( did not look at the version sp and other detail of my
installation). Add the code to a new file and compiled and run …

Compiler output -

--------------------Configuration: ComplierTest - Win32
Debug--------------------
Compiling…
compliertest.c
c:\src\compliertest\compliertest.c(18) : warning C4715: ‘main’ : not all
control paths return a value
Linking…

ComplierTest.exe - 0 error(s), 1 warning(s)

Running the debug version ( the output is )

C:\src\ComplierTest\Debug>ComplierTest.exe
Testing!
Hello

-pro

On 5/16/07, Raja Reddy wrote:

Hello,

Today I found a serious problem in the following code when I compiled
with VC++ 6.

The installed compiler & linker versions are 12.00.8804, 6.00.8447 on
x86 system respectively.

#include <stdio.h>

int alloc()
{
return 0;
}

int main(int argc, char* argv)
{
printf(“Testing!\n”);

if(alloc() == 0)
goto Radhe;

return 0;

Radhe:

printf(“Hello\n”);

}

I expected that “Hello” will be printed just once because, the if
statement jumps the instruction pointer to the label.

But “Hello” is priting always till I kill the process.

When I check the assembly code, I found a JMP instruction right after
printf(“Hello\n”) line, instead of a RET instruction.

I don’t know whether this is known bug in VC compilers or microsoft
standard. I just want to share this with all of experts here.

If this is the wrong place to post, please ignore.

Regards,

Raja Reddy.

________________________________

Park yourself in front of a world of choices in alternative vehicles.
Visit the Yahoo! Auto Green Center.
http:ylc=X3oDMTE5cDF2bXZzBF9TAzk3MTA3MDc2BHNlYwNtYWlsdGFncwRzbGsDZ3JlZW4tY2Vu
dGVy> — Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</http:></stdio.h>

Raja Reddy wrote:

Hello,

Today I found a serious problem in the following code when I compiled
with VC++ 6.
The installed compiler & linker versions are 12.00.8804, 6.00.8447 on
x86 system respectively.

I expected that “Hello” will be printed just once because, the if
statement jumps the instruction pointer to the label.

But “Hello” is priting always till I kill the process.
When I check the assembly code, I found a JMP instruction right after
printf(“Hello\n”) line, instead of a RET instruction.

I don’t know whether this is known bug in VC compilers or microsoft
standard. I just want to share this with all of experts here.

Have you kept up with all of the service packs for VC6? I just compiled
this with the 12.00.8804 compiler and 6.00.8447 linker, and it worked
perfectly fine. There is a jump statement after the printf, but it
jumps directly to the “xor eax,eax” that returns from main. I have
service pack 6.

; 15 :
; 16 : Radhe:
; 17 : printf(“Hello\n”);

00026 68 00 00 00 00 push OFFSET FLAT:$SG779
0002b e8 00 00 00 00 call _printf
00030 83 c4 04 add esp, 4

; 18 : }

00033 eb 02 jmp SHORT $L785
$L775:
00035 eb 02 jmp SHORT $L784
$L785:
00037 33 c0 xor eax, eax
$L784:
00039 5d pop ebp
0003a c3 ret 0
_main ENDP
_TEXT ENDS
END


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

raj_r wrote:

well not hoping to turn this thread into a you you me me flame war

but gotos do have thier use and i ve seen some very good code being
being emitted when using gotos

and being constantly fed wtih propaganda against using gotos i asked
someone
about the phenomena
i have a the best possible code emitted by the compiler when i am
using goto
in my c source (no embedded jumps inserted but compiler was clever
enough to seamlessly merge the code into a single proc with goto)

but it seems every tom dick and harry and his poodle out there is
fanatic about me not using goto

Fanaticism is not the right attitude. However, there are facts here
that cannot be denied. One very good measure of the “complexity” of a
computer program is the number of times the path of control changes (via
‘if’, ‘while’, ‘for’, ‘goto’, etc.), and it has been amply demonstrated
in academic research that programs which are more “complicated” by that
measure are more difficult to write, more difficult to debug, more
difficult to understand, and more difficult to debug.

Yes, it is quite possible that you can use “goto” to microoptimize a
program. The problem with that is that human time is infinitely more
valuable than computer time. Someday, after you’ve moved on to other
things, someone else will have to read your code. If that goto causes
them to waste 15 minutes to understand what you’ve written, then the
microseconds that you saved by including it were anything but an
“optimization”.

No one should be telling you “never use gotos”. However, in virtually
every instance where your instincts tell you to reach for a “goto”,
there are ways to accomplish the same thing that are easier to understand.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Exactly, Maxim. Also, in the SEH realm, I wonder how the dev feels
about __leave?

>> xxxxx@storagecraft.com 2007-05-17 03:29 >>>
You shouldn’t use gotos. Avoid them. In a world of exceptions and
encapsulated init/deinit there is no need for gotos.

Kernel does not support C++ exceptions.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Mike Kemp wrote:

Surely the only important issue here is (as Maxim said) that any
complier should issue an error that not all control paths return a
value. Any that don’t have not parsed it correctly.

Since the source code is invalid C the results if it does (appear to)
compile must be garbage.

That source code is completely valid and standard-compliant C. It is
perfectly legal in the C standard to flow off the end of “main” without
an explicit return statement.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I haven’t tried this, but I wonder if the fact that it is “main” has
anything to do with the lack of warning, due to main being able to have
at least three possible valid definitions. Also, of course, this whole
issue depends entirely on how one builds this code (-w), and potentially
#pragmas buried somewhere.

As far as goto, I basically agree with Tim here, with the addition that
ease of understanding and ease of debugging are sometimes at odds with
each other with regards to returning control paths. In particular,
related to the goto issue it is sometimes said that there should be only
one “return” in a function. This is, ignoring optimizations, easier to
debug, but, in my opinion, the nested “if” mess that following the rule
can create in many cases is not by a long shot easier to understand than
multiple returns. I think the case can be made (as the author of NT
File System Internals does) for goto in some cases, although I am not a
disciple of that school of thought. Also, although I am a frequent use
of both SEH and C++ EH, I personally find statements to the effect that
these are show how “simpler” than basically any other form of flow
control patently absurd. They are obfuscating. I still find them worth
it overall, because they are cleaner, but they are certainly no
panacea.

mm

>> xxxxx@sintefex.com 2007-05-17 04:51 >>>
Surely the only important issue here is (as Maxim said) that any
complier
should issue an error that not all control paths return a value. Any
that
don’t have not parsed it correctly.

Since the source code is invalid C the results if it does (appear to)
compile must be garbage.

I think we all find complier anomalies from time to time, presumably
most
people, like me, find a workaround and move on. Reporting it to the
supplier
is more public spirited, but we seldom have time.

BTW I thought goto was a valid part of the language. Most of us were
taught
that a good rule of thumb is to avoid them as there is often a better
architecture. These rules are of course for the the guidance of the
wise
(and the obediance of ??? - I can’t remember the original quote…).

Mike

----- Original Message -----
From: raj_r
To: Windows System Software Devs Interest List
Sent: Thursday, May 17, 2007 9:08 AM
Subject: Re: [ntdev] Strange problem with VC++ compiler because of
goto

well not hoping to turn this thread into a you you me me flame war

but gotos do have thier use and i ve seen some very good code being
being emitted when using gotos

and being constantly fed wtih propaganda against using gotos i asked
someone
about the phenomena
i have a the best possible code emitted by the compiler when i am using
goto
in my c source (no embedded jumps inserted but compiler was clever
enough to seamlessly merge the code into a single proc with goto)

but it seems every tom dick and harry and his poodle out there is
fanatic about me not using goto

and he replied something in this vein

using goto is like dividing by zero
in school mathematics dividing by zero is impossible cannot be done
in highschool mathematics you get the tone of dividing by zero is
acceptable with certain caveats

when you are doing college mathematics
you can certainly divide by zero and derive a result that tends to some

limit

not sure the analogy fits in or not but i do believe in some cases
gotos have the best possible outcome of compiled code

no flames please

On 5/17/07, Edouard A. wrote:
> To avoid this problem the best is to have strict guidelines about
that
> kind
> of stuff within your team(s). When new people come into the team they
are
> made aware of the rules, which are:
>
> 1/You do not talk about GOTO
> 2/You DO NOT talk about GOTO
>
> –
>
> EA
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com [mailto:bounce-286997-
> > xxxxx@lists.osr.com] On Behalf Of Robert Kennett
> > Sent: jeudi 17 mai 2007 09:06
> > To: Windows System Software Devs Interest List
> > Subject: Re: [ntdev] Strange problem with VC++ compiler because of
goto
> >
> > I find that goto’s are one of the most singularly useful
constructs
> > there is. Just one or two, placed at strategic points in the code,
will
> > derail any serious code review while the participant flame each
other
> > into fits and ignoring the substance of the code. Goto’s also work
> > great
> > for turning ntdev into slashdot. Any thoughts on genetically
altered
> > corn?
> >
> >
> >
> > > I don’t mean the snap but.
> > >
> > >
> > >
> > > You shouldn’t use gotos. Avoid them. In a world of exceptions
and
> > > encapsulated init/deinit there is no need for gotos. I recently
saw a
> > > code with gotos INSIDE a loop that went UP and since that minute
I
> > > decided that my tolerance toward gotos ended.
> > >
> > >
> > >
> > > –
> > >
> > > EA
> > >
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] *On Behalf Of Raja
Reddy
> > > Sent: jeudi 17 mai 2007 06:44
> > > To: Windows System Software Devs Interest List
> > > Subject: [ntdev] Strange problem with VC++ compiler because of
goto
> > >
> > > Hello,
> > >
> > > Today I found a serious problem in the following code when I
compiled
> > > with VC++ 6.
> > >
> > > The installed compiler & linker versions are 12.00.8804,
6.00.8447 on
> > > x86 system respectively.
> > >
> > > #include <stdio.h>
> > >
> > > int alloc()
> > > {
> > > return 0;
> > > }
> > >
> > > int main(int argc, char
argv)
> > > {
> > > printf(“Testing!\n”);
> > >
> > > if(alloc() == 0)
> > > goto Radhe;
> > >
> > > return 0;
> > >
> > > Radhe:
> > >
> > > printf(“Hello\n”);
> > >
> > > }
> > >
> > > I expected that “Hello” will be printed just once because, the
if
> > > statement jumps the instruction pointer to the label.
> > >
> > > But “Hello” is priting always till I kill the process.
> > >
> > > When I check the assembly code, I found a JMP instruction right
after
> > > printf(“Hello\n”) line, instead of a RET instruction.
> > >
> > > I don’t know whether this is known bug in VC compilers or
microsoft
> > > standard. I just want to share this with all of experts here.
> > >
> > > If this is the wrong place to post, please ignore.
> > >
> > > Regards,
> > >
> > > Raja Reddy.
> > >
> > >
---------------------------------------------------------------------
> > —
> > >
> > > Park yourself in front of a world of choices in alternative
vehicles.
> > > Visit the Yahoo! Auto Green Center.
> > >
> >
http:> >
_ylc=X3oDMTE5cDF2bXZzBF9TAzk3MTA3MDc2BHNlYwNtYWlsdGFncwRzbGsDZ3JlZW4tY2
> > VudGVy>
> > > — Questions? First check the Kernel Driver FAQ at
> > > http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit
the
> > > List Server section of OSR Online at
> > > http://www.osronline.com/page.cfm?name=ListServer
> > >
> > >
> > > —
> > > Questions? First check the Kernel Driver FAQ at
> > > http://www.osronline.com/article.cfm?id=256
> > >
> > > To unsubscribe, visit the List Server section of OSR Online at
> > > http://www.osronline.com/page.cfm?name=ListServer
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer</http:></stdio.h>

> ----------

From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Tim Roberts[SMTP:xxxxx@probo.com]
Reply To: Windows System Software Devs Interest List
Sent: Thursday, May 17, 2007 7:20 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Strange problem with VC++ compiler because of goto

That source code is completely valid and standard-compliant C. It is
perfectly legal in the C standard to flow off the end of “main” without
an explicit return statement.

Really? It is “int main” not “void main”. Well, maybe is main an exception, I don’t remember.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

> ----------

From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Tim Roberts[SMTP:xxxxx@probo.com]
Reply To: Windows System Software Devs Interest List
Sent: Thursday, May 17, 2007 7:18 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Strange problem with VC++ compiler because of goto

No one should be telling you “never use gotos”. However, in virtually
every instance where your instincts tell you to reach for a “goto”,
there are ways to accomplish the same thing that are easier to understand.

Hmm, I use goto almost exclusively to make my code easier to understand :slight_smile:

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

Maxim S. Shatskih wrote:

> You shouldn’t use gotos. Avoid them. In a world of exceptions and
> encapsulated init/deinit there is no need for gotos.
>

Kernel does not support C++ exceptions.

However, much to my surprise, it turns out this is not too hard to
implement. Through another client, I encountered a kernel framework
library written by Walter Oney that, through the inclusion of a couple
of magic functions, makes C++ exception handling work in 98 and NT
kernel drivers.

Personally, it scared me. I set it gently down and backed slowly
towards the door, but there was no denying that it did work.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks tim

i was just wanting to understand a little bit about the insights of
everyone telling not to use goto

nothing more nothing less im not trying to advocate its usage
but definately there seems to be places where goto produces better code

the code some thing like

if(count>=32)
{
//your code here
goto label
}
else
{
label:
// some other code
}

is where i noticed goto merging the else clause into a single proc

if should execute,else should execute and in some special cases if
should execute and else should also execute

as an aside

i compiled this in borland
it seems to emit a warning
and then runs fine

Desktop>bcc32 spin.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
spin.c:
Warning W8065 spin.c 11: Call to function ‘alloc’ with no prototype in function
main
Warning W8070 spin.c 18: Function should return a value in function main
Warning W8057 spin.c 18: Parameter ‘argc’ is never used in function main
Warning W8057 spin.c 18: Parameter ‘argv’ is never used in function main
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

Desktop>spin.exe
Testing!
Hello

\Desktop>

the disassembly looks fine
00401150 /$ 55 PUSH EBP
00401151 |. 8BEC MOV EBP,ESP
00401153 |. 33C0 XOR EAX,EAX
00401155 |. 5D POP EBP ;
kernel32.77E814C7
00401156 . C3 RETN
00401157 /. 55 PUSH EBP
00401158 |. 8BEC MOV EBP,ESP
0040115A |. 68 28A14000 PUSH spin.0040A128 ;
/Arg1 = 0040A128 ASCII "Testing!
"
0040115F |. E8 20270000 CALL spin.00403884 ;
\spin.00403884
00401164 |. 59 POP ECX ;
kernel32.77E814C7
00401165 |. E8 E6FFFFFF CALL spin.00401150
0040116A |. 85C0 TEST EAX,EAX
0040116C |. 74 04 JE SHORT spin.00401172
0040116E |. 33C0 XOR EAX,EAX
00401170 |. 5D POP EBP ;
kernel32.77E814C7
00401171 |. C3 RETN
00401172 |> 68 32A14000 PUSH spin.0040A132 ;
ASCII "Hello
"
00401177 |. E8 08270000 CALL spin.00403884
0040117C |. 59 POP ECX ;
kernel32.77E814C7
0040117D |. 5D POP EBP ;
kernel32.77E814C7
0040117E . C3 RETN

thanks and regards

raj_r

On 5/17/07, Tim Roberts wrote:
> raj_r wrote:
> > well not hoping to turn this thread into a you you me me flame war
> >
> > but gotos do have thier use and i ve seen some very good code being
> > being emitted when using gotos
> >
> > and being constantly fed wtih propaganda against using gotos i asked
> > someone
> > about the phenomena
> > i have a the best possible code emitted by the compiler when i am
> > using goto
> > in my c source (no embedded jumps inserted but compiler was clever
> > enough to seamlessly merge the code into a single proc with goto)
> >
> > but it seems every tom dick and harry and his poodle out there is
> > fanatic about me not using goto
>
> Fanaticism is not the right attitude. However, there are facts here
> that cannot be denied. One very good measure of the “complexity” of a
> computer program is the number of times the path of control changes (via
> ‘if’, ‘while’, ‘for’, ‘goto’, etc.), and it has been amply demonstrated
> in academic research that programs which are more “complicated” by that
> measure are more difficult to write, more difficult to debug, more
> difficult to understand, and more difficult to debug.
>
> Yes, it is quite possible that you can use “goto” to microoptimize a
> program. The problem with that is that human time is infinitely more
> valuable than computer time. Someday, after you’ve moved on to other
> things, someone else will have to read your code. If that goto causes
> them to waste 15 minutes to understand what you’ve written, then the
> microseconds that you saved by including it were anything but an
> “optimization”.
>
> No one should be telling you “never use gotos”. However, in virtually
> every instance where your instincts tell you to reach for a “goto”,
> there are ways to accomplish the same thing that are easier to understand.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

> That source code is completely valid and standard-compliant C. It is

I never remembered anything in Stroustrup/Ellis book about the possibility of
not all non-void function return paths to return a value.

It is at least a C++ error.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

raj_r wrote:

nothing more nothing less im not trying to advocate its usage
but definately there seems to be places where goto produces better code

How do you define “better” in this case? If you mean “it runs in 12
microseconds instead of 14 microseconds”, then you are focusing on the
wrong metric.

the code some thing like

if(count>=32)
{
//your code here
goto label
}
else
{
label:
// some other code
}

is where i noticed goto merging the else clause into a single proc

if should execute,else should execute and in some special cases if
should execute and else should also execute

You’re saying that the Borland compiler happened to compile that
intelligently, and that’s fine. The KEY point is that it probably would
have compiled it just as intelligently if you had written it like this:

bool bDoSecondPart = false;
if( count >= 32 )
{
// your code here
if( … )
bDoSecondPart = true;
}
else
bDoSecondPart = true;

if( bDoSecondPart )
{
// some other code
}

and writing it that way makes the intent of the code much more explicit.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Maxim S. Shatskih wrote:

> That source code is completely valid and standard-compliant C. It is
>

I never remembered anything in Stroustrup/Ellis book about the possibility of
not all non-void function return paths to return a value.

It is at least a C++ error.

Not in this case.

The C++ standard does say that the end of a function has an implied
“return;” with no value, and that flowing into it results in undefined
behavior in a “value-returning function”. However, in section 3.6.1 it
also says:
If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;

The C99 standard says the same thing in a slightly different way in
5.1.2.2.3.

So, this program is valid in both C99 and C++.

I can’t find a C90 standard any more.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I know one context where use of goto does seem to give more
easily maintained code. This is when freeing allocated
resources under error conditions in the absence of
exception handling.

This is the ugly version:

{
A *a;
B *b;
C *c;
D *c;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
{
FreeA(a);
return FAILED;
}

c = AllocateC();
if(c == NULL)
{
FreeA(a);
FreeB(b);
return FAILED;
}

d = AllocateD();
if(d == NULL)
{
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}

return SUCCESS;
}

See how you have to carefully arrange exactly the
right deallocations for each failure. Its a real
pain to add new allocations somewhere in such
a sequence.

Here is the prettier version:

{
A *a = NULL;
B *b = NULL;
C *c = NULL;
D *c = NULL;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
goto failure;

c = AllocateC();
if(c == NULL)
goto failure;

d = AllocateD();
if(d == NULL)
goto failure;

return SUCCESS;

failure:
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}

Except you left out all the {}'s after the if’s :slight_smile:

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Paul Gardiner
Sent: Thursday, May 17, 2007 3:30 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Strange problem with VC++ compiler because of goto

I know one context where use of goto does seem to give more
easily maintained code. This is when freeing allocated
resources under error conditions in the absence of
exception handling.

This is the ugly version:

{
A *a;
B *b;
C *c;
D *c;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
{
FreeA(a);
return FAILED;
}

c = AllocateC();
if(c == NULL)
{
FreeA(a);
FreeB(b);
return FAILED;
}

d = AllocateD();
if(d == NULL)
{
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}

return SUCCESS;
}

See how you have to carefully arrange exactly the
right deallocations for each failure. Its a real
pain to add new allocations somewhere in such
a sequence.

Here is the prettier version:

{
A *a = NULL;
B *b = NULL;
C *c = NULL;
D *c = NULL;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
goto failure;

c = AllocateC();
if(c == NULL)
goto failure;

d = AllocateD();
if(d == NULL)
goto failure;

return SUCCESS;

failure:
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Matter of taste :slight_smile: I prefer {} after ifs, too.

Unfortunately, WDK samples use the first way which is not only ugly but also error prone.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Peter Wieland[SMTP:xxxxx@windows.microsoft.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, May 18, 2007 1:38 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Strange problem with VC++ compiler because of goto

Except you left out all the {}'s after the if’s :slight_smile:

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Paul Gardiner
Sent: Thursday, May 17, 2007 3:30 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Strange problem with VC++ compiler because of goto

I know one context where use of goto does seem to give more
easily maintained code. This is when freeing allocated
resources under error conditions in the absence of
exception handling.

This is the ugly version:

{
A *a;
B *b;
C *c;
D *c;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
{
FreeA(a);
return FAILED;
}

c = AllocateC();
if(c == NULL)
{
FreeA(a);
FreeB(b);
return FAILED;
}

d = AllocateD();
if(d == NULL)
{
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}

return SUCCESS;
}

See how you have to carefully arrange exactly the
right deallocations for each failure. Its a real
pain to add new allocations somewhere in such
a sequence.

Here is the prettier version:

{
A *a = NULL;
B *b = NULL;
C *c = NULL;
D *c = NULL;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
goto failure;

c = AllocateC();
if(c == NULL)
goto failure;

d = AllocateD();
if(d == NULL)
goto failure;

return SUCCESS;

failure:
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Some do, some don’t. none of the ones I’ve written do (or at least the ones I’ve written recently :))

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Michal Vodicka
Sent: Thursday, May 17, 2007 4:49 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Strange problem with VC++ compiler because of goto

Matter of taste :slight_smile: I prefer {} after ifs, too.

Unfortunately, WDK samples use the first way which is not only ugly but also error prone.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Peter Wieland[SMTP:xxxxx@windows.microsoft.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, May 18, 2007 1:38 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Strange problem with VC++ compiler because of goto

Except you left out all the {}'s after the if’s :slight_smile:

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Paul Gardiner
Sent: Thursday, May 17, 2007 3:30 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Strange problem with VC++ compiler because of goto

I know one context where use of goto does seem to give more
easily maintained code. This is when freeing allocated
resources under error conditions in the absence of
exception handling.

This is the ugly version:

{
A *a;
B *b;
C *c;
D *c;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
{
FreeA(a);
return FAILED;
}

c = AllocateC();
if(c == NULL)
{
FreeA(a);
FreeB(b);
return FAILED;
}

d = AllocateD();
if(d == NULL)
{
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}

return SUCCESS;
}

See how you have to carefully arrange exactly the
right deallocations for each failure. Its a real
pain to add new allocations somewhere in such
a sequence.

Here is the prettier version:

{
A *a = NULL;
B *b = NULL;
C *c = NULL;
D *c = NULL;

a = AllocateA();
if(a == NULL)
return FAILED;

b = AllocateB();
if(b == NULL)
goto failure;

c = AllocateC();
if(c == NULL)
goto failure;

d = AllocateD();
if(d == NULL)
goto failure;

return SUCCESS;

failure:
FreeA(a);
FreeB(b);
FreeC(c);
return FAILED;
}


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

So I probably never encountered any of your samples :slight_smile: Couldn’t you rewrite the rest of them? :wink:

All I saw used the same style. It was so consistent I expected it is mandatory. Consistency it good but the style isn’t. It wastefully consumes vertical space. When I based my (the first and the last forever) project on one of samples, code after reformating and refactoring had 1/3 of lines and was much easier to read, at least for me :slight_smile:

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Peter Wieland[SMTP:xxxxx@windows.microsoft.com]
Reply To: Windows System Software Devs Interest List
Sent: Friday, May 18, 2007 1:59 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Strange problem with VC++ compiler because of goto

Some do, some don’t. none of the ones I’ve written do (or at least the ones I’ve written recently :))

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Michal Vodicka
Sent: Thursday, May 17, 2007 4:49 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Strange problem with VC++ compiler because of goto

Matter of taste :slight_smile: I prefer {} after ifs, too.

Unfortunately, WDK samples use the first way which is not only ugly but also error prone.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

> ----------
> From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of Peter Wieland[SMTP:xxxxx@windows.microsoft.com]
> Reply To: Windows System Software Devs Interest List
> Sent: Friday, May 18, 2007 1:38 AM
> To: Windows System Software Devs Interest List
> Subject: RE: [ntdev] Strange problem with VC++ compiler because of goto
>
> Except you left out all the {}'s after the if’s :slight_smile:
>
> -p
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Paul Gardiner
> Sent: Thursday, May 17, 2007 3:30 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] Strange problem with VC++ compiler because of goto
>
> I know one context where use of goto does seem to give more
> easily maintained code. This is when freeing allocated
> resources under error conditions in the absence of
> exception handling.
>
> This is the ugly version:
>
> {
> A *a;
> B *b;
> C *c;
> D *c;
>
> a = AllocateA();
> if(a == NULL)
> return FAILED;
>
> b = AllocateB();
> if(b == NULL)
> {
> FreeA(a);
> return FAILED;
> }
>
> c = AllocateC();
> if(c == NULL)
> {
> FreeA(a);
> FreeB(b);
> return FAILED;
> }
>
> d = AllocateD();
> if(d == NULL)
> {
> FreeA(a);
> FreeB(b);
> FreeC(c);
> return FAILED;
> }
>
> return SUCCESS;
> }
>
> See how you have to carefully arrange exactly the
> right deallocations for each failure. Its a real
> pain to add new allocations somewhere in such
> a sequence.
>
> Here is the prettier version:
>
> {
> A *a = NULL;
> B *b = NULL;
> C *c = NULL;
> D *c = NULL;
>
> a = AllocateA();
> if(a == NULL)
> return FAILED;
>
> b = AllocateB();
> if(b == NULL)
> goto failure;
>
> c = AllocateC();
> if(c == NULL)
> goto failure;
>
> d = AllocateD();
> if(d == NULL)
> goto failure;
>
> return SUCCESS;
>
> failure:
> FreeA(a);
> FreeB(b);
> FreeC(c);
> return FAILED;
> }
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256\>
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

This is the most beautiful one (choose your own IF formatting):

{
Ptr a = AllocateA();
if(a == NULL) return FAILED;

Ptr **b = AllocateB();
if(b == NULL) return FAILED;

Ptr c = AllocateC();
if(c == NULL) return FAILED;

return SUCCESS;
}

“Paul Gardiner” wrote in message news:xxxxx@ntdev…
>I know one context where use of goto does seem to give more
> easily maintained code. This is when freeing allocated
> resources under error conditions in the absence of
> exception handling.
>
> This is the ugly version:
>
> {
> A *a;
> B *b;
> C *c;
> D *c;
>
> a = AllocateA();
> if(a == NULL)
> return FAILED;
>
> b = AllocateB();
> if(b == NULL)
> {
> FreeA(a);
> return FAILED;
> }
>
> c = AllocateC();
> if(c == NULL)
> {
> FreeA(a);
> FreeB(b);
> return FAILED;
> }
>
> d = AllocateD();
> if(d == NULL)
> {
> FreeA(a);
> FreeB(b);
> FreeC(c);
> return FAILED;
> }
>
> return SUCCESS;
> }
>
> See how you have to carefully arrange exactly the
> right deallocations for each failure. Its a real
> pain to add new allocations somewhere in such
> a sequence.
>
> Here is the prettier version:
>
> {
> A *a = NULL;
> B *b = NULL;
> C c = NULL;
> D c = NULL;
>
> a = AllocateA();
> if(a == NULL)
> return FAILED;
>
> b = AllocateB();
> if(b == NULL)
> goto failure;
>
> c = AllocateC();
> if(c == NULL)
> goto failure;
>
> d = AllocateD();
> if(d == NULL)
> goto failure;
>
> return SUCCESS;
>
> failure:
> FreeA(a);
> FreeB(b);
> FreeC(c);
> return FAILED;
> }
>

hi,

the problem with multiple returns in a function (especially in larger ones) is often, that some resources which are acquired (most often later during a change of the code) in that function are not freed at exit of the function because of an early “return”.

Therefore - after hard discussions - we have the rule in our larger projects that each larger function has to have a label - most often named "exitFunction: " or so - near the end of the function. And everybody has to use “goto exitFunction” to leave the function. After that label all resources must be freed. Of course you have to keep track there which resources are really acquired when you reach this part of the code.

And I think that it is completely structured code although there are those “gotos” inside the code. We have this discussion about gotos again and again, but I discuss about coding guidelines since more than 35 years now. It is very hard for my colleagues to argue with me about that point :wink:

– Reinhard