POINTER NULL CHECK

General FreeBASIC programming questions.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

POINTER NULL CHECK

Post by Munair »

Consider the following code:

Code: Select all

dim handle as any ptr

if handle = NULL then ... ' OK
if not handle then ... ' error: wrong type argument to bit-complement
The error tells me that the NOT HANDLE test isn't supported. So is the first test HANDLE = NULL effective? Or is there more to it to see whether a pointer is assigned?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: POINTER NULL CHECK

Post by jj2007 »

This works fine for me:

Code: Select all

dim handle as any ptr

if handle = 0 then Print "NULL"
if not handle then Print "Handle="; handle

handle=1
if handle = 0 then Print "NULL"
if not handle then Print "Handle="; handle

Sleep
Output:

Code: Select all

NULL
Handle=0
Handle=1
Check also the output for

Code: Select all

if not handle then Print "not handle=";not handle
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Post by fxm »

When compiling with gcc, complement a pointer is disallowed (works with gas).
gcc is stricter (or gas more lax)

Workaround:

Code: Select all

dim handle as any ptr

if handle = NULL then ... ' handle = 0
if handle then ... ' handle <> 0
or

Code: Select all

dim handle as any ptr

if handle = NULL then ... ' handle = 0
if handle <> NULL then ... ' handle <> 0
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: POINTER NULL CHECK

Post by MrSwiss »

Munair wrote:So is the first test HANDLE = NULL effective?
No, it isn't, use: 0 (instead of NULL), since NULL might NOT be, defined!
(it isn't "native", aka: default defined, by compiler)

Btw: please, stop SHOUTING at us (all upper case, means that!)
Last edited by MrSwiss on Nov 26, 2017 15:27, edited 1 time in total.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: POINTER NULL CHECK

Post by Munair »

MrSwiss wrote:
Munair wrote:So is the first test HANDLE = NULL effective?
No, it isn't, use: 0 (instead of NULL), since NULL might NOT be, defined!
(it isn't "native", aka: default defined, by compiler)
I defined it as 0 in my library. ;)
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: POINTER NULL CHECK

Post by Munair »

fxm wrote:When compiling with gcc, complement a pointer is disallowed (works with gas).
gcc is stricter (or gas more lax)

Workaround:

Code: Select all

dim handle as any ptr

if handle = NULL then ... ' handle = 0
if handle then ... ' handle <> 0
or

Code: Select all

dim handle as any ptr

if handle = NULL then ... ' handle = 0
if handle <> NULL then ... ' handle <> 0
I noticed. Thanks.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: POINTER NULL CHECK

Post by jj2007 »

Munair wrote:
fxm wrote:When compiling with gcc, complement a pointer is disallowed (works with gas).
gcc is stricter (or gas more lax)
The problem is maybe that some programmers don't pay much attention to the consequences:

Code: Select all

Dim handleI as integer
Dim handleB as boolean

handleI=123
handleB=123

if not handleI then
  print "not a handle: ";not handleI
else
  print "valid handle: "; handleI
endif

if not handleB then
  print "not a handle: ";not handleB
else
  print "valid handle: "; handleB
endif

Sleep
Output:

Code: Select all

not a handle: -124
valid handle: true
Or, in other words: integer <> boolean ;-)
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: POINTER NULL CHECK

Post by Munair »

That also includes POINTER <> BOOLEAN.

However, testing non-complementary boolean does work:

Code: Select all

dim handle as any ptr

if handle then ... ' works
if not handle then ... 'doesn't work
;)
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Post by fxm »

When not testing Boolean but numeric values, the most correct expressions are for example (works with gas and gcc):

Code: Select all

dim handle as any ptr
dim k as integer

If ( handle = k ) Then ... ' OK
If ( handle <> k ) Then ... ' OK
If Not ( handle = k ) Then ... ' OK
If Not ( handle <> k ) Then ... ' OK
(including the case k = 0)

Another example, I don't like the syntax:

Code: Select all

If Len(string) Then ...
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: POINTER NULL CHECK

Post by Munair »

fxm wrote:Another example, I don't like the syntax:

Code: Select all

If Len(string) Then ...
In QuickBASIC, testing with LEN produced faster code than with quotes:

Code: Select all

if len(MyString) then... ' faster
if MyString <> "" then ... 'slower
same for an empty string:

Code: Select all

if len(MyString) = 0 then... ' faster
if MyString = "" then ... ' slower
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Post by fxm »

fxm wrote:Another example, I don't like the syntax:

Code: Select all

If Len(string) Then ...
I thought rather:

Code: Select all

If Len(string) > 0 Then ...
(not omitting "> 0")
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: POINTER NULL CHECK

Post by dodicat »

not x seems to be simply -(x+1)
So a custom not seems trivial to make, handling integers/floats/pointers.

Code: Select all



#define pnot(x) -(cast(integer,x)+1)


print "integers"
for n as long=1 to 20
    var x=int(rnd*100-rnd*100)
print x,not x,pnot(x)
next
print

redim as long a(1 to 200001)

print "Pointers"
dim as any ptr p

for n as long=1 to 20
     p=@a(1+rnd*20000)
      if n=10 then p=0
    print p,pnot(p)
next

print
print "test 2000000 doubles"
for n as long=1 to 2000000
    var x=(rnd*1000000-rnd*1000000)
    if not(x)<>pnot(x) then print x,"error"
next
print "done"
sleep




 
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: POINTER NULL CHECK

Post by Munair »

fxm wrote:I thought rather:

Code: Select all

If Len(string) > 0 Then ...
(not omitting "> 0")
I agree.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: POINTER NULL CHECK

Post by jj2007 »

fxm wrote:Another example, I don't like the syntax:

Code: Select all

If Len(string) Then ...

Code: Select all

Dim MyString as string="123"

asm int 3 
if len(MyString) Then
	print "ifLen"
endif
asm int 3 
if len(MyString)>0 Then
	print "ifLenGtzero"
endif

Code: Select all

Address         Hex dump              Command                                 Comments
0040161B        ³.  CC                int3
0040161C        ³.  6A FF             push -1                                 ; ÚArg2 = -1
0040161E        ³.  8D45 E8           lea eax, [ebp-18]                       ; ³
00401621        ³.  50                push eax                                ; ³Arg1 => offset LOCAL.6
00401622        ³.  E8 49120000       call 00402870                           ; ÀTmpFile.00402870
00401627        ³.  85C0              test eax, eax
00401629        ³. 74 0E             jz short 00401639
0040162B        ³.  6A 01             push 1                                  ; ÚArg3 = 1
0040162D        ³.  68 40804000       push offset 00408040                    ; ³Arg2 = UNICODE "ifLen"
00401632        ³.  6A 00             push 0                                  ; ³Arg1 = 0
00401634        ³.  E8 C7080000       call 00401F00                           ; ÀTmpFile.00401F00
00401639        ³>  CC                int3
0040163A        ³.  6A FF             push -1                                 ; ÚArg2 = -1
0040163C        ³.  8D45 E8           lea eax, [ebp-18]                       ; ³
0040163F        ³.  50                push eax                                ; ³Arg1 => offset LOCAL.6
00401640        ³.  E8 2B120000       call 00402870                           ; ÀTmpFile.00402870
00401645        ³.  85C0              test eax, eax
00401647        ³. 7E 0E             jle short 00401657
00401649        ³.  6A 01             push 1                                  ; ÚArg3 = 1
0040164B        ³.  68 4C804000       push offset 0040804C                    ; ³Arg2 = UNICODE "ifLenGtzero"
00401650        ³.  6A 00             push 0                                  ; ³Arg1 = 0
00401652        ³.  E8 A9080000       call 00401F00                           ; ÀTmpFile.00401F00
The only difference: jz (jump zero) vs jle (jump less or equal). Since it is difficult to imagine a string with a negative length, the practical relevance is rather low...
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Post by fxm »

fxm wrote:Another example, I don't like the syntax:

Code: Select all

If Len(string) Then ...
Obviously this syntax compiles well and works but this code BASIC is not "clean" in my humble opinion, because the expression 'Len (string)' is neither true nor false, but conversely the expression 'Len (string) = 0' is true or false.
Here, I talk about the quality of the source code!
Post Reply