News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

"If the function fails, the return value is NULL"

Started by raleeper, March 11, 2012, 06:01:09 PM

Previous topic - Next topic

raleeper

Is it safe to assume that this means "If and only if the function fails, the return value is NULL"?

jj2007

Pretty safe. Usually MSDN tells you explicitly to check with GetLastError if zero as regular return value makes sense (a rare case anyway).

Gunner

Never assume anything.  GlobalFree returns NULL on success!!!  There are a few API calls that return NULL on success.  Just read the documentation for the function.
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

Vortex

Gunner is right. Here is another example :

RegOpenKeyEx
RegQueryValueEx
RegCloseKey


All those three functions are returning ERROR_SUCCESS on success :

ERROR_SUCCESS equ 0

raleeper

I didn't phrase my question clearly enough. It is a question about the wording of the Microsoft documentation.

In using the API and its documentation, I am not interested in determining the return based on success or failure; I am interested in determinimg success or failure based on the return.  Logically, the quoted language authorizes only the first (uninteresting) determination - unless the "if" is interpreted as "only if" or "if and only if".

Sometimes,.but not always, the quoted the quoted language is accompanied by something like
Quote"If the function succeeds, the return is a pointer ..."
.  Together the 2 statements do authorize the interesting determinations, but only on the (very reasonable) assumption that a function succeds if and only if it does not fail.

dedndave

if the documentation states "If the function fails, the return value is zero."

then, yes - it is "if and only if"
Jochen found a case the other day that seemed a little odd with SendMessage
however, the return value for SendMessage varies with different messages
also - it may depend on how well the WndProc for the hWnd was written   :P
because it determines what value is returned

one that i find particularly odd is SetFilePonter   :bg
i think they had too many martinis at lunch, then came back and defined the behaviour of that function - lol
i generally write a "wrapper" function that calls it and hides all the clumsiness

jj2007

Quote from: Gunner on March 11, 2012, 06:47:58 PM
Never assume anything.  GlobalFree returns NULL on success!!!  There are a few API calls that return NULL on success.  Just read the documentation for the function.

Gunner,
As the thread title says, Robert means calls where MSDN clearly states "if it fails, it returns zero". However, there are a handful of cases (and I don't have any at hand) where zero is also a valid return value. In these cases, MSDN tells you to check if GetLastError flags an error. If it doesn't, then zero is your valid return value.

hutch--

I would suggest that there is no single return value that is universal, in every instance you need to look at the documentation for the function is to get the return value significance.

Take a common sort comparison result, > 0, 0 and < 0. There are in fact many others and it depends on what the function is performing as to what the return value may happen to be. 0 is often a successful return value so it is not wise to assume that it always indicates an error.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

donkey

Quote from: raleeper on March 11, 2012, 06:01:09 PM
Is it safe to assume that this means "If and only if the function fails, the return value is NULL"?

You can assume exactly the opposite in COM, if the function succeeds the return value is always S_OK (0). For Flat API functions 0 means failure as often as it means success, however if a flat API function succeeds GetLastError will return 0 (ERROR_SUCCESS). There are a few cases such as CreateMutex where a partial success will not return 0 from GetLastError such as when an attempt is made to create a named mutex that already exists, the mutex handle is still returned but GetLastError returns ERROR_ALREADY_EXISTS. So, you must read the API documentation and treat each API as a unique case, except when using COM, it always returns 0 for success.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jj2007

Quote from: donkey on March 12, 2012, 02:30:19 AMhowever if a flat API function succeeds GetLastError will return 0 (ERROR_SUCCESS).

There are many functions that do not change GetLastError if they succeed. However, if
1. Microsoft says "if it fails, it returns zero"
2. A zero may nonetheless be a valid "successful" return value
then you need a call to GetLastError to verify whether the zero is an error or not.

sinsi

Quote from: Gunner on March 11, 2012, 06:47:58 PM
Never assume anything.  GlobalFree returns NULL on success!!!  There are a few API calls that return NULL on success.  Just read the documentation for the function.
Yes, but GlobalFree returns a handle/pointer, so NULL would be correct.

Generally, if you expect a handle or a pointer as a return value, NULL means failure. Of course, check the documentation before assuming...
Light travels faster than sound, that's why some people seem bright until you hear them.

donkey

Quote from: jj2007 on March 12, 2012, 06:19:21 AM
There are many functions that do not change GetLastError if they succeed.

True, my mistake. I tend to forget about the functions that don't set the last error code, its rare that I bother to check it except where it is used to specify that there is more data like FindNextFile or for CreateMutex where it is used for exclusion. Mostly I use the RTFM method and can just do a case by case check of the return value.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

raleeper

Quote from: jj2007 on March 12, 2012, 06:19:21 AM
Quote from: donkey on March 12, 2012, 02:30:19 AMhowever if a flat API function succeeds GetLastError will return 0 (ERROR_SUCCESS).

There are many functions that do not change GetLastError if they succeed. However, if
1. Microsoft says "if it fails, it returns zero"
2. A zero may nonetheless be a valid "successful" return value
then you need a call to GetLastError to verify whether the zero is an error or not.

Let me see if I have this right.
Quote1. Microsoft says "if it fails, it returns zero"
2. A zero may nonetheless be a valid "successful" return value
So if I get a zero I still need (to be completely safe) to call GetLastError.
But if
QuoteThere are many functions that do not change GetLastError if they succeed
how do I know whether the return from GetLastError pertains to the function just called. or is left over from a previous function.

The function that started me thinking about this was GetOpenFileName, which returns 0
QuoteIf the user cancels or closes the Open dialog box or an error occurs
(from MSDN}.  So here the documentation alerts the programmer that 0 does not always mean failure for this function.

I think I will assume that a 0 means failure (when Microsoft says "if it fails, it returns zero") and rely on MS not to say "if it fails, it returns zero" unless this means "if and only if it fails, it returns zero"

Thanks, robert

jj2007

Quote from: raleeper on March 12, 2012, 12:55:25 PM

The function that started me thinking about this was GetOpenFileName, which returns 0
QuoteIf the user cancels or closes the Open dialog box or an error occurs
(from MSDN}.  So here the documentation alerts the programmer that 0 does not always mean failure for this function.

Robert,

In 99% of those cases where the docu says "zero on error", you don't need an extra check. In the remaining 1% of cases, the last error code MUST be set by the API to ensure the users knows the reason (either valid zero, or an error). The docu will invite the user explicitly to use GetLastError.

GetOpenFileName is indeed one of those stupid examples where you better check if the user aborted (0) or whether there was a crash somewhere (0). In both cases, you can't open the file in lpstrFile...

Tedd

If the docs say a function returns NULL on failure, then NULL will be returned only in the event of failure, otherwise you can expect a legitimate usable value. But not all functions return NULL to indicate failure.

For those functions that return a pointer, then the failure value is usually NULL, since that's not a valid pointer reference (by convention.) Whereas, functions that return a numeric value could legitimately return zero and so they must have some other way to indicate failure (sometimes another value, sometimes setting 'last-error.')

But there's no strict consistency for indicating success/failure, so it's advisable to check the docs for each and every function. ::)
No snowflake in an avalanche feels responsible.