?? Suspicious pointer assignment ??

General FreeBASIC programming questions.
TJF
Posts: 3486
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

?? Suspicious pointer assignment ??

Postby TJF » Dec 04, 2012 16:10

This snippet

Code: Select all

SUB test(BYVAL M AS INTEGER PTR)
  VAR Tok = "123412341234123412341234"
  VAR t = CAST(INTEGER PTR, SADD(Tok)), a = t

#PRINT TYPEOF(a)
#PRINT TYPEOF(M)
#PRINT TYPEOF(t)

  a = M - t

END SUB


results to this output when compiling (fbc-0.24, LINUX)

Code: Select all

fbc -exx -w all "test.bas" (im Verzeichnis: test)
INTEGER PTR
INTEGER PTR
INTEGER PTR
test.bas(11) warning 4(1): Suspicious pointer assignment
Kompilierung erfolgreich beendet.


I cannot find any reason for a " Suspicious pointer assignment" !?!
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: ?? Suspicious pointer assignment ??

Postby Gonzo » Dec 04, 2012 16:31

strange bug =) i can't see anything wrong
since var is defined as a type implied from its initializer, there is no doubt that all the results must be integer ptr

i still don't understand your preference for var, which creates ambigous code for human reading
but that's another matter you can regret when re-reading your code years from now :P
TJF
Posts: 3486
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: ?? Suspicious pointer assignment ??

Postby TJF » Dec 04, 2012 16:48

Gonzo wrote:i still don't understand your preference for var, which creates ambigous code for human reading ...

You're right, in this snippet there's no advantage.

But when you use external libraries it's much faster to code

    VAR middle = g_sequence_range_get_midpoint (s, e)
instead of searching for the right type in the documentation and then code

    DIM AS GSequenceIter PTR middle = g_sequence_range_get_midpoint (s, e)
without any typo. And for me it's more readable too, since I don't care about the type -- I just pass the variable to other functions (unless I have to hunt a bug).

At least it's more convenient : )

Anyway, thanks for your statement.
dkl
Site Admin
Posts: 3210
Joined: Jul 28, 2005 14:45
Location: Germany

Re: ?? Suspicious pointer assignment ??

Postby dkl » Dec 04, 2012 17:03

Interesting behaviour, I didn't know it even existed... Subtracting two pointers of the same type returns the difference in terms of "items" or "units", not bytes, i.e. it's reverse pointer arithmetic:

Code: Select all

dim as integer ptr p0 = new integer[10]
dim as integer ptr p1 = p0 + 1
dim as integer ptr p2 = p0 + 2
dim as integer ptr p3 = p0 + 3

print p0, p1, p2, p3
print p0 - p0, p1 - p0, p2 - p0, p3 - p0

#print typeof( p0 )
#print typeof( p1 )
#print typeof( p1 - p0 )


as such the result type of the subtraction is an integer, not a pointer. It makes sense to me; the difference of two addresses won't be an address itself. I always use cuint() to avoid pointer arithmetic in this case (note that the difference is then given in bytes, not "items", but it's still not an address):

Code: Select all

print cuint( p0 ) - cuint( p0 ), cuint( p1 ) - cuint( p0 ), cuint( p2 ) - cuint( p0 ), cuint( p3 ) - cuint( p0 )
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: ?? Suspicious pointer assignment ??

Postby Gonzo » Dec 04, 2012 17:41

crap :)

dkl is right as explained here:

Code: Select all

ptrdiff_t    <cstddef>
Result of pointer subtraction
This is the type returned by the subtraction operation between two pointers. This is a signed integral type, and as such can be casted to compatible fundamental data types.


http://www.cplusplus.com/reference/cstddef/ptrdiff_t/
D.J.Peters
Posts: 7852
Joined: May 28, 2005 3:28

Re: ?? Suspicious pointer assignment ??

Postby D.J.Peters » Dec 04, 2012 18:08

Code: Select all

SUB test(BYVAL M AS INTEGER PTR)
  VAR Tok = "123412341234123412341234"
  VAR t = CAST(INTEGER PTR, SADD(Tok)), a = t
  a = cast(TYPEOF(a),M-t)
END SUB
counting_pine
Site Admin
Posts: 6174
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: ?? Suspicious pointer assignment ??

Postby counting_pine » Dec 04, 2012 18:11

Code: Select all

SUB test(BYVAL M AS INTEGER PTR)
  VAR Tok = "123412341234123412341234"
  VAR t = CAST(INTEGER PTR, SADD(Tok)), a = M-t
END SUB
fxm
Posts: 9306
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: ?? Suspicious pointer assignment ??

Postby fxm » Dec 04, 2012 18:38

Yes, but:

Code: Select all

SUB test(BYVAL M AS INTEGER PTR)
  VAR Tok = "123412341234123412341234"
  VAR t = CAST(INTEGER PTR, SADD(Tok)), a = M-t
  #PRINT TYPEOF(a)
END SUB
Compiler output:
UINTEGER

Why 'a' is an Uinteger and not an Integer?
MOD
Posts: 555
Joined: Jun 11, 2009 20:15

Re: ?? Suspicious pointer assignment ??

Postby MOD » Dec 04, 2012 19:56

Because #PRINT TYPEOF(M-t) is an UINTEGER.

A Pointer is just a UInteger value. If you're using operators on it, it seems to see it as UInteger and therefore returns an UInteger. So VAR makes 'a' an UInteger.
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: ?? Suspicious pointer assignment ??

Postby Gonzo » Dec 04, 2012 20:03

MOD wrote:Because #PRINT TYPEOF(M-t) is an UINTEGER.

A Pointer is just a UInteger value. If you're using operators on it, it seems to see it as UInteger and therefore returns an UInteger. So VAR makes 'a' an UInteger.


that makes absolutely no sense, especially when the manual (ptrdiff_t) explicitly says it must be a signed integer (of the appropriate/any type)
think about the result of the calculation: print @a(0) - @a(1), which is negative
much like a date difference can be negative to show that one date came before the other

edit: meant @a(0) - @a(1)
Last edited by Gonzo on Dec 04, 2012 21:01, edited 1 time in total.
MOD
Posts: 555
Joined: Jun 11, 2009 20:15

Re: ?? Suspicious pointer assignment ??

Postby MOD » Dec 04, 2012 20:08

Code: Select all

Dim As Integer a(1)
#Print TypeOf(@a(1) - @a(0))
fxm
Posts: 9306
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: ?? Suspicious pointer assignment ??

Postby fxm » Dec 04, 2012 20:22

It's crazy!

Code: Select all

Dim As Double array(1)

Dim As Byte offsetB
offsetB = @array(1) - @array(0)
Print offsetB
offsetB = @array(0) - @array(1)
Print OffsetB
Print
Dim As Integer offsetI
offsetI = @array(1) - @array(0)
Print offsetI
offsetI = @array(0) - @array(1)
Print OffsetI
Sleep

Code: Select all

 1
-1

 1
 536870911

Code: Select all

Dim As Double array(1)

Dim As Byte offsetB
offsetB = Cast(Byte Ptr, @array(1)) - Cast(Byte Ptr, @array(0))
Print offsetB
offsetB = Cast(Byte Ptr, @array(0)) - Cast(Byte Ptr, @array(1))
Print OffsetB
Print
Dim As Integer offsetI
offsetI = Cast(Integer Ptr, @array(1)) - Cast(Integer Ptr, @array(0))
Print offsetI
offsetI = Cast(Integer Ptr, @array(0)) - Cast(Integer Ptr, @array(1))
Print OffsetI
Sleep

Code: Select all

 8
-8

 2
 1073741822

Only the offset defined as Byte is well supported!
counting_pine
Site Admin
Posts: 6174
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: ?? Suspicious pointer assignment ??

Postby counting_pine » Dec 04, 2012 20:56

That makes sense.
Because it's using unsigned integers, and hence unsigned division, negative values aren't divided correctly (except by 1 obviously).

Code: Select all

#define ptrdiff(t, a, b) (cptr(t ptr, a) - cptr(t ptr, b))
#define ptrdiffs(t, a, b) ((cint(a) - cint(b)) \ sizeof(t))
#define ptrdiffu(t, a, b) ((cuint(a) - cuint(b)) \ sizeof(t))

Dim As Double a(0 to 1)

print "signed"
print ptrdiffs(double, @a(1), @a(0)), ptrdiffs(double, @a(0), @a(1))
print ptrdiffs(integer, @a(1), @a(0)), ptrdiffs(integer, @a(0), @a(1))
print ptrdiffs(byte, @a(1), @a(0)), ptrdiffs(byte, @a(0), @a(1))
print

print "unsigned"
print ptrdiffu(double, @a(1), @a(0)), ptrdiffu(double, @a(0), @a(1))
print ptrdiffu(integer, @a(1), @a(0)), ptrdiffu(integer, @a(0), @a(1))
print ptrdiffu(byte, @a(1), @a(0)), ptrdiffu(byte, @a(0), @a(1))
print

print "FB"
print ptrdiff(double, @a(1), @a(0)), ptrdiff(double, @a(0), @a(1))
print ptrdiff(integer, @a(1), @a(0)), ptrdiff(integer, @a(0), @a(1))
print ptrdiff(byte, @a(1), @a(0)), ptrdiff(byte, @a(0), @a(1))
print

Code: Select all

signed
 0             0
 0             0
 1            -1

unsigned
0             536870911
0             1073741823
1             4294967295

FB
0             536870911
0             1073741823
1             4294967295

The high values are because the sign bit is treated as 2^31 instead of -2^31.

So the fix looks like it would be simply to change the result of the subtraction from unsigned to signed, which thankfully concurs with what Gonzo says.
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: ?? Suspicious pointer assignment ??

Postby Gonzo » Dec 04, 2012 21:03

consistency is king =)
if it doesn't make sense, don't do it, even if qb says otherwise
at least, i wish that was the official mantra :(

obligatory mentioning of missing feature: sizeof(a())
counting_pine
Site Admin
Posts: 6174
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: ?? Suspicious pointer assignment ??

Postby counting_pine » Dec 04, 2012 21:07

Is that in Feature Requests?

Anyway, I can't commit atm, but I suspect the unsigned->signed fix lies in the following three lines:
https://github.com/freebasic/fbc/blob/0 ... p.bas#L682

EDIT: Fixed in https://github.com/freebasic/fbc/commit/c15aaf0

Return to “General”

Who is online

Users browsing this forum: Majestic-12 [Bot] and 4 guests