tags:

views:

159

answers:

8

Hello,

I am using a API that has a macro for success which is "NT_SUCCESS". However they don't have one for failure. So normally I have to do this.

if(something failed)
    return !NT_SUCCESS;
else
   return NT_SUCCESS;

Having the !NT_SUCCESS I don't think is very readable. So I decided to do this:

#define SUCCESS NT_SUCCESS
#define FAILURE (!NT_SUCCESS)

EDIT =============================

#define ENT_NOERR 0 /* No error */ 
#define NT_SUCCESS ENT_NOERR /* synonym of ENT_NOERR */ 

This is how NT_SUCCESS is declared, Would it still be ok to do what I have done.

Would that be ok?

Many thanks for any suggestions,

+2  A: 

that would be ok

Marco Schmid
+1  A: 

Are you sure that logically negated value of NT_SUCCESS is an indication of failure?

Anton Gogolev
Yes, that would indicate a failure.
robUK
+5  A: 

I would suggest to put the FAILURE define in parenthesis:

#define FAILURE (!NT_SUCCESS)
LiraNuna
What difference would adding parentheses do? Thanks
robUK
It's arithmetically safer and insures it will always be evaluated in the order you specify.
LiraNuna
#define SIX 1+5....#define NINE 8+1...assert(SIX * NINE == 42);
Yuliy
A: 

If you want to be truly paranoid, you should add parentheses:

#define FAILURE (!NT_SUCCESS)
R Samuel Klatchko
What difference would adding parentheses do? Thanks.
robUK
In general, it's recommended to use parentheses when defining macros so that you don't get unexpected results due to simple textual substitution combined with operator precedence.
R Samuel Klatchko
@robUK: You should spend some time reading through the comp.lang.c FAQ. In particular: http://c-faq.com/cpp/safemacros.html
jamesdlin
@James. Thanks. At the time I thought maybe it was ok as it was just one operator. Thanks for correcting me.
robUK
-1: I'm not sure why you wouldn't delete this post and just upvote/comment on Lira's instead, she obviously had the same answer as you, before you....
gnarf
-1 from me...LiraNuna answered first before you! Don't embellish and improvise other people's answers to get a rep gain for your own gain!
tommieb75
@gnarf - our two answers were posted 26 seconds apart. Yes, it would have been better for me to have noticed it and then deleted my answer.
R Samuel Klatchko
@tommieb75 - our two answers were posted 26 second apart. I think it's more likely that I answered independently and didn't notice her answer.
R Samuel Klatchko
+1  A: 

Well, it actually depends. It's a little unusual for you to return the same error values as an API you're calling. The only times I can see this would be required is if either:

  • you're actually returning a value back from a callback initiated within the API.
  • you're replacing code in the API so have to follow the same rules.

It may be that NT_SUCCESS is 0 but a failure can be indicated by any other integer. That means that !NT_SUCCESS is not the only value that means failure.

Of course, you're free to pass back from your API whatever values you wish, I wouldn't necessarily make them the same as the ones from the API you're using. You could quite easily return a failure indication (true = fail, false = success) which would make your code the much nicer looking:

return something_failed;

or, at worst,

if (something_failed) return TRUE;
: : :
return FALSE;
paxdiablo
+4  A: 

I would add parentheses for good measure, but otherwise you should be OK:

#define FAILURE (!(NT_SUCCESS))

This is "just in case", to prevent bad definitions such as #define NT_SUCCESS 1+1. Of course, no sane implementation would do this, so your definition should be okay too. But it can't hurt to be paranoid. :-)

Alok
+1  A: 

It's not ok, at least not until you know how NT_SUCCESS is defined. It can be defined as #define NT_SUCCESS 1 or as #define NT_SUCCESS TRUE

In the second case it makes sense to write !NT_SUCCESS, so your code is ok, but in the first case, writing !NT_SUCCESS means !1, which doesn't make any sense. In the second case you would be better off with:

#define SUCCESS NT_SUCCESS
#define FAILURE -1 //or other value which makes sense

It's up to you.

BROCK
!1 makes perfect sense. It's 0. !x is defined as 0 if x is nonzero, and 1 if x is 0.
Yuliy
#define ENT_NOERR 0 /* No error */
robUK
#define NT_SUCCESS ENT_NOERR /* synonym of ENT_NOERR */
robUK
I have just checked how it is defined. So NT_SUCCESS is set to 0. So I guess !NT_SUCCESS is the same as !0. Would this be correct to do what I have done with my marcos?
robUK
+1  A: 

This can not possibly be correct. Surely you are supposed to return some kind of error code that gives the caller a chance to find out why it didn't work?

Hans Passant