-3

in a WDF driver project I'm writing in Visual Studio 2013, I've got this function:

ZwWaitForSingleObject(hSemaphore, 0);

which gives the "too few arguments in function call" error, if I omit the last parameter, which is optional:

    NTSTATUS ZwWaitForSingleObject(
  _In_     HANDLE         Handle,
  _In_     BOOLEAN        Alertable,
  _In_opt_ PLARGE_INTEGER Timeout
);

The problem is, I have to omit it, I cannot just set it to NULL. Because, as MSDN says:

If a Timeout parameter is not specified, then the wait will not be satisfied until the object attains a state of Signaled. If an explicit Timeout value of zero is specified, then no wait will occur if the wait cannot be satisfied immediately.

So, the question is: have you got any idea on why Visual C++ forces me to type in the optional parameter on a system function call? How can it be avoided?

Flavio
  • 451
  • 3
  • 26
  • Is the extension of your file `.c`? – Mohit Jain Jul 29 '15 at 13:42
  • 3
    It's not "optional" as in C++ default argument. It is a pointer, so you should be passing NULL. – Banex Jul 29 '15 at 13:43
  • @MohitJain Yes. But I also tried to set it to .cpp, and I also set the "Compile as C++ Code (/TP)" option, but doesn't solve. – Flavio Jul 29 '15 at 13:45
  • 1
    C does not have "optional" parameters. Tag changed to C++ – pmg Jul 29 '15 at 13:46
  • @Banex, the problem is, if I set the Timeout parameter to zero, as MSDN says, the behaviour of ZwWaitForSingleObject will be different then NOT specyfing it – Flavio Jul 29 '15 at 13:47
  • Did you try passing third parameter as NULL? `ZwWaitForSingleObject(hSemaphore, 0, 0);` – Mohit Jain Jul 29 '15 at 13:47
  • 1
    To expand on the comment by @Banex, WIN32 types which have a prefix `P` means they are pointer types, `PLARGE_INTEGER` is a *pointer* to `LARGE_INTEGER`. Since the functions have to be callable from C as well as C++, they can't have arguments with default values (which is a C++ specific feature), and so pointers are used, and to the "optional" part is that the pointer have to be `NULL` if the argument is not to be used. Also, in C++, `0` *is* the null pointer (a.k.a. `NULL`). So passing `0` as the third argument is the same as passing `NULL`. – Some programmer dude Jul 29 '15 at 13:51

2 Answers2

4

zero is not the same as NULL. This is a C API, there are no "optional" parameters. So passing NULL means not specified The two cases in your quoted documentation are

ZwWaitForSingleObject(handle, 0, NULL);
/* or ZwWaitForSingleObject(handle, 0, 0); which is the same */

vs

LARGE_INTEGER timeout;
timeout.QuadPart = 0L;
ZwWaitForSingleObject(handle, 0, &timeout);
  • Thank you for the prompt response, now I understand. I didn't think about the difference between passing a valid pointer to a null value, and passing a null pointer. – Flavio Jul 29 '15 at 14:01
1

It's optional as in: you don't have to pass a valid value if you don't want to but you have to pass something, the optional parameters don't work the same as a default argument in C++ (even though this question is already tagged as C).

The variable type of Timeout is PLARGE_INTEGER which is a pointer to a LARGE_INTEGER. Creating a LARGE_INTEGER and setting it's values to 0 and passing the created LARGE_INTEGER will cause the behaviour you specified :

If an explicit Timeout value of zero is specified, then no wait will occur if the wait cannot be satisfied immediately.

However, this won't happen when you simply pass NULL as argument, it's the same as a Timeout parameter is not specified.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122