# goto considered harmful within global macros

This topic is 2080 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I was really quite surprised when I first attempted to add error checking at work, and my compilation failed with a error: use of undeclared label 'onError'.

From a ubiquitous global header in a (thankfully recently deceased) library within our project:

#define CheckSuccess(condition) do { \
if (!condition) { \
goto onError; \
} \
} while (0) 

The idea that an error checking macro would require the current function to implement a specifically named label for error cleanup (or, indeed, that there would be significant error cleanup not handled by RAII), is a little unpleasant to me...

I should probably add that the author of this particular gem thought that they were working around the lack of exception handling on our target platform.

Yikes.

Dear god o.O

##### Share on other sites

Meh, macros like this are common in C programs. Also popular:

#define CHECK(x) do { if(err = (x)) goto error; } while(0)

to save the actual error code (and assuming 0 = no error), which requires a variable of the appropriate type in addition to the proper goto label.

It should probably not be defined in a global header though.

Edited by l0calh05t

##### Share on other sites

I'm 100% surprised a velociraptor attack did not ensue. That macro only saves you from typing 7 keystrokes too... totally not worth using it IMO. And I hate macros like that for debugging and stepping through code.

Also, condition really should've been in parentheses (like in l0calh05t's post), because other wise things like CheckSuccess(false || true) would've resulted in madness.

##### Share on other sites

I feel something in my bowels. I'm going AFK a few minutes.

##### Share on other sites
The real WTF is that other half of the error handling system isn't hidden behind an equivalent macro
#define CheckSuccess(condition) do { \
if (!condition) { \
goto onError; \
} \
} while (0)

#define OnError do { if(false) { \
onError: (void)0
#define EndError }} while (0) 
I mean, come on, if you're going to abstract away half of your error handling system behind your own invented keyword, at least be consistent and apply the same abstraction to the other half of the system too! Edited by Hodgman

##### Share on other sites

The real WTF is that other half of the error handling system isn't hidden behind an equivalent macro

#define CheckSuccess(condition) do { \
if (!condition) { \
goto onError; \
} \
} while (0)

#define OnError do { if(false) { \
onError: (void)0
#define EndError }} while (0) 

WTF Indeed  .

##### Share on other sites

On the rare occasions I need macros that are specific to a function or small set of related functions, I define them in the source file and then #undef them afterward. I've yet to put a goto in one though...

• 21
• 11
• 9
• 17
• 13