POINTER NULL CHECK

General FreeBASIC programming questions.
Munair
Posts: 834
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

POINTER NULL CHECK

Postby Munair » Nov 26, 2017 12:31

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: 1180
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: POINTER NULL CHECK

Postby jj2007 » Nov 26, 2017 12:41

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
Posts: 9015
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Postby fxm » Nov 26, 2017 13:43

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: 3128
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: POINTER NULL CHECK

Postby MrSwiss » Nov 26, 2017 14:23

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: 834
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: POINTER NULL CHECK

Postby Munair » Nov 26, 2017 15:26

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: 834
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: POINTER NULL CHECK

Postby Munair » Nov 26, 2017 15:27

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: 1180
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: POINTER NULL CHECK

Postby jj2007 » Nov 26, 2017 16:31

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: 834
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: POINTER NULL CHECK

Postby Munair » Nov 26, 2017 16:45

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
Posts: 9015
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Postby fxm » Nov 26, 2017 17:16

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: 834
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: POINTER NULL CHECK

Postby Munair » Nov 26, 2017 17:38

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
Posts: 9015
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Postby fxm » Nov 26, 2017 17:42

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: 5825
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: POINTER NULL CHECK

Postby dodicat » Nov 26, 2017 18:40

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: 834
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: POINTER NULL CHECK

Postby Munair » Nov 26, 2017 19:25

fxm wrote:I thought rather:

Code: Select all

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

Re: POINTER NULL CHECK

Postby jj2007 » Nov 26, 2017 20:46

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
Posts: 9015
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: POINTER NULL CHECK

Postby fxm » Nov 26, 2017 21:04

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!

Return to “General”

Who is online

Users browsing this forum: Google [Bot] and 3 guests