Re: Best Practices For Thread-Safe errno
On Oct 12, 3:38 am, Seungbeom Kim <musip...@bawi.org> wrote:
Some functions have more than a simple success/failure to say:
e.g. what if you requested to send 200 bytes and only 100 bytes could
have been sent at the moment? Is that a success or a failure?
The programmer would have to decide, but to me it smells like success.
If the number of bytes sent or not sent is stored in a separate out-
parameter, that is a duplication of information between the return
value and the out-parameter in some way: in any case, the out-parameter
saying that all the requested bytes are sent should imply that the
return value is true.
I would do exactly that - store the number of bytes actually sent in a
variable of type unsigned int returned by reference.
Look at lstat(), the POSIX's equivalent to SetFilePointer():
off_t lseek(int fd, off_t offset, int whence);
Upon successful completion, lseek() returns the resulting offset
location as measured in bytes from the beginning of the file.
Otherwise, a value of (off_t) -1 is returned and errno is set to
indicate the error.
This is as simple as it can be.
This particular example has an interesting history. I once saw an ad
from early 1980's about a "software package" that would magically
break the 2GB limit on file sizes on a mainframe computer (and hence
seeking). The "software package" cost several thousand US dollars at
the time. We all know what happened here - the full 32-bit width was
cut in half from the outset because the type of the file size was made
signed, for reasons which we all understand and have discussed ad
nauseum.
Here is Google search on the effect of signed return types, and hence
signed file sizes:
http://tinyurl.com/yzpmque
[Note to Mods: I do not know how to create a preview TinyURL.]
{ verified to be a link to a Google search of "2gb file size limit". -mod }
Note that my primary reason for going the unsigned route would not be
to capture the other 2GB linear space, though that would be an
influence. My primary reaosn would be to move into a regular mode of
thinking regarding function calls. I seek mental relief. IHMO,
true=success/false=failure provides greater mental relief. It "reads"
better than the other models like "< 0 means error."
There is a bit of intermingling of computer/human semantics of
language at play here. It is the same principle that drives a library
designer to prefix the name of a member function with the word "is".
He anticipates that users of his library will be using it in certain
way, and he accommodates the mode of thought in the user of his
library:
bool Digital_Address:is_archaic() const;
Digital_Address da;
if (da.is_archaic()) // this reads well. subject/predicate/object
// yada...
I got into had a bad experience regarding "How Well Does It Read?"
recently:
We had a memory leak in one of our Windows Shell Namespace Extensions.
We had all kinds of heavy machinery trying to track it down. We
finally concluded that no object in our entire, super-complex project
was leaking memory, because we went over each line of code line by
line [extremely painful].
The bug turned out to be a mistake we made using a Microsoft function
that does not read well:
DllCanUnloadNow
http://msdn.microsoft.com/en-us/library/ms690368(VS.85).aspx
You would think that Microsoft would let this function return TRUE to
say "Yes, you can unload.", and FALSE, to say, "No you cannot
unload.", but because it is technically a COM function, and COM
functions use heavy overloading of return type, as espoused by others
in this thread, TRUE/FALSE was not quite available.
In a nutshell, an EXE calls this function that lives inside a DLL to
determine if it is OK to detach the DLL from the process space.
Microsoft writes at beginning of the man page:
"If the function succeeds, the return value is S_OK. Otherwise, it is
S_FALSE"
Then at the end:
"DllCanUnloadNow should return S_FALSE if there are any existing
references to objects that the DLL manages."
A careless programmer [moi], might make a mistake, and say, "S_FALSE
is one of the values...so...S_TRUE, or just TRUE must be the other. I
will return TRUE if it is OK to unload."
And that's what I did. I return S_FALSE when there were existing
references, when it was not OK to unload, and TRUE when where not, so
that TRUE meant "OK to unload."
Then someone, perhaps moi again, saw the S_FALSE several months later
and removed the "S_", so that, if it was OK to unload, we were
returning TRUE, and FALSE, if not.
But in Windows, TRUE has value 1. S_FALSE, also has the value 1. FALSE
has value 0, S_OK has the value 0.
*** Note that S_OK == 0 derives precisely from the principle that 0
should ne "no error", as said by some in this thread. ***
So by returning FALSE, from a function, which, linguistically expanded
in English, reads "DLL can unload now..", say as to say "No, the DLL
cnannot unload now..", we were actualy say "Yes, The DLL can unload
now." By returning TRUE, so as to say that the DLL could unload, we
were actually saying, "No, the DLL cannot unload".
It took us several days of intense hunting to find this bug until I
realized that it could not possibly be our core code.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]