is "return((void*)1)" safe?

Started by
47 comments, last by Nitage 15 years ago
Quote:Original post by floatingwoods
The returned data is a buffer that can contain anything. The length of that buffer is specified by its first DWORD.


Then you have a simple solution.

For the special case, return NULL.

For the "normal, no data" case, return a buffer that is 1 DWORD long, where that DWORD's value is 0.

But making "buffers" of that sort is a really bad idea in a language like C++. I strongly suspect that "anything" is not really as variable as you think. :)
Advertisement
Quote:Original post by loufoque
Quote:But anyways, I felt the urge (for fun) to hack together a class that represents either a type A, xor a type B.

You mean something like boost::variant<A, B>, but way not as good?


You mean "You mean something like boost::variant<A, B>, but way not as good?", without understanding the post that you have replied to?

Let me explain in detail, just for you:
  • "for fun" -> "As a joke, not seriously", "for the fun of it; for kicks. For pleasure or excitement." (click)
  • "not for production use" -> not intended to be used actively (click)
And finally:
  • "Hack" -> "Originally, a quick job that produces what is needed, but not well." (click)


loufoque, just out of curiosity, is your horizon limited to using what others wrote, or have you something to actually show off?


edit:revised explanations

[Edited by - phresnel on April 27, 2009 10:25:32 AM]
Quote:Original post by visitor
How well would be that work in a multithreading program? (It seems to me that the entire C pattern of using globals and statics is a bit problematic.)


It's fine for that (constant, read-only), but globals can be problematic due to linking, especially once DLLs come into play. It's an extra thing to worry about, and potentially a timed bomb.

Quote:For the special case, return NULL.

For the "normal, no data" case, return a buffer that is 1 DWORD long, where that DWORD's value is 0.
This would IMHO be the sanest approach if designing from scratch.

But considering this seems to be existing codebase, there is probably existing code using the function. By changing the contents of return value, but not its semantics, everything will still compile just fine, even though the returned data may now be used incorrectly.

I'd prefer API breaking change that would cause caller to fail to compile vs. stealthy change in contents.

Or, the return value should be something just barely safer, if C++:
struct Result {  size_t count;  DWORD * data;  // or whatever way the implicit conversion is actually declared  operator DWORD*() const { return data; }; };

This should preserve the logic while (perhaps) not breaking existing code, and allow for special case, perhaps even via some additional error states indicated by Result itself.

[Edited by - Antheus on April 27, 2009 10:45:53 AM]
Quote:Original post by visitor
Are you sure that an exception would be entirely inappropriate?

There are consoles, from the current console generation, for which the compiler documentation explicitly says not to enable exceptions, that the code generated is broken, and that it WILL crash and burn if an exception is ever actually triggered.

So yes, as a general rule, Exceptions are entirely inappropriate.
Quote:Original post by Antheus
Quote:For the special case, return NULL.

For the "normal, no data" case, return a buffer that is 1 DWORD long, where that DWORD's value is 0.
This would IMHO be the sanest approach if designing from scratch.

But considering this seems to be existing codebase, there is probably existing code using the function. By changing the contents of return value, but not its semantics, everything will still compile just fine, even though the returned data may now be used incorrectly.

I'd prefer API breaking change that would cause caller to fail to compile vs. stealthy change in contents.


In general, that is true. But here, the return types I describe appear to be in agreement with the stated public interface. :) I mean, the caller will have to check the length field of the data anyway, and if it reads a 0 there, it should be obvious what that means.

If we were designing from scratch we'd actually do something more typesafe and memory-management-safe than returning an allocated memory buffer, yeah? :)
#define SUCCESS 1#define FAIL    -1int so_simple_even_a_child_could_write_it( int iValue, void** pOut ){    if( iValue > 0 )    {        *pOut = new int[iValue];        return (pOut != NULL) ? SUCCESS : FAIL;    }    return FAIL;}
Sorry :-)
I'm afraid you forgot to define FILE_NOT_FOUND. :)
You forgot also to make it RAII compliant, making it crap. Sorry for being harsh.

Also the code is obviously stupid.

If you dereference pOut, you already know pOut is not null (so why check it afterwards) or you have raised undefined behaviour.
You probably wanted to use nothrow new and to check for the result of the allocation?

Anyway that's really really bad.
Either code the ugly C way or the nice C++ way.
Quote:Original post by loufoque
You forgot also to make it RAII compliant, making it crap. Sorry for being harsh.

Also the code is obviously stupid.

If you dereference pOut, you already know pOut is not null (so why check it afterwards) or you have raised undefined behaviour.
You probably wanted to use nothrow new and to check for the result of the allocation?

Anyway that's really really bad.
Either code the ugly C way or the nice C++ way.


You have no sense of humour. Killjoy.
Quote:Original post by Namethatnobodyelsetook
Quote:Original post by visitor
Are you sure that an exception would be entirely inappropriate?

There are consoles, from the current console generation, for which the compiler documentation explicitly says not to enable exceptions, that the code generated is broken, and that it WILL crash and burn if an exception is ever actually triggered.

So yes, as a general rule, Exceptions are entirely inappropriate.


In C++ exceptions are the appropriate way of handling exceptional circumstances. If you're using a compiler that implements C++ without exceptions then of course they aren't appropriate - but then that isn't a 'general rule', it's a special case.

This topic is closed to new replies.

Advertisement