I have tried to find clear rules regarding the use of NULL or 0 in MASM. A forum search for MessageBox reveals that about half the posts use NULL, the other half uses 0. Chances that Microsoft (or Linux, Apple?) replace one day NULL with something different from 0h are almost nil, sorry: NULL (please tell me if this assumption is FALSE or TRUE).
What are the views of experienced programmers? Pragmatic or purist? One argument might be readability...
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, ADDR AppName, \
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, \
CW_USEDEFAULT, 300, 200, NULL, NULL, hInst, NULL
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, ADDR AppName, \
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, \
CW_USEDEFAULT, 300, 200, 0, 0, hInst, 0
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, ADDR AppName,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, 300, 200, 0, 0, hInst, 0
P.S.: I once stumbled over an API that required a pointer to a NULL string, i.e. a memory location containing a 0 byte, but I do not I remember which one. Most calls "know" that the value 0 passed as a pointer means there is no string waiting at the other end. Does anybody have a list of API calls that lack this intelligence?
For me it's mostly an attempt to match the Microsoft documentation. I try to use null where the documentation uses null, and 0 where the documentation uses 0.
I use 0 everywhere, shorter to write, cleaner code; NULL EQUs 0, it's very unlikely that this will change.
I tend to be selective depending on the semantics of the function call, if NULL makes the semantics of the call clearer I use it, if a procedure requires zero I use "0" instead.
I tend to use NULL to represent a null pointer and 0 otherwise.
I vote with Ghirari
Quote from: Greg on April 12, 2008, 04:17:18 PM
I tend to use NULL to represent a null pointer and 0 otherwise.
CreateWindowEx:
lpWindowName
Points to a null-terminated string that specifies the window name
invoke CreateWindowEx,
0, addr szClassName,
0, etc
or
invoke CreateWindowEx,
0, addr szClassName,
NULL, etc
Not 100% compatible with the MSDN documentation, but it works, as we all know. Still looking for a list of those that don't work...
Anyway, I can live with 0, NULL and FALSE. What I find TRUEly embarassing is the choice of 1 for TRUE:
3 and TRUE != 3
3 and TRUE ==1
What I find a problem is
TRUE != True != true != TruE etc.
Quote from: jj2007Not 100% compatible with the MSDN documentation ...
How is it not 100% compatible? lpWindowName is a pointer.
Quote from: Greg on April 12, 2008, 06:05:24 PM
Quote from: jj2007Not 100% compatible with the MSDN documentation ...
How is it not 100% compatible? lpWindowName is a pointer.
Well, that pointer points to address 0, not to a null$; often, MSDN says explicitly that the pointer can be NULL but not in this case.
Different example, CreateProcess:
lpProcessAttributes
A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle to the new process object can be inherited by child processes. If lpProcessAttributes is NULL, the handle cannot be inherited.
Quote from: Jimg on April 12, 2008, 05:43:20 PM
What I find a problem is
TRUE != True != true != TruE etc.
But at least MASM spits you in the face if you make that mistake:
undefined symbol : False
undefined symbol : True
undefined symbol : true
undefined symbol : false
It won't complain if you use
(edit)
.if eax==4 & TRUE
Assuming that eax==4 that condition is FALSE...
(edit again, hmmm, I should really test my code before posting :red)
mov eax, 4
mov var1, eax
.if var1 & TRUE
invoke MessageBox, 0, chr$("True"), chr$("Test"), MB_OK
.else
invoke MessageBox, 0, chr$("False"), chr$("Test"), MB_OK
.endif
Quote from: jj2007Well, that pointer points to address 0, not to a null$; often, MSDN says explicitly that the pointer can be NULL but not in this case.
I see what you are saying.
FWIW, I prefer to use NULL for null pointers, FALSE for booleans (I try to avoid using TRUE). Most of the time I prefer to use Windows API data types to just DWORD, i.e. HANDLE. I also prefer to define a pointer as pointer, i.e. PBYTE. The reason is readability and self-documentation.
Some people on this forum completely disagree with that view.
There are times when it is really handy to be able to just use DWORD for a 32-bit Windows API data type.