fb 1.07 tests

General discussion for topics related to the FreeBASIC project or its community.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fb 1.07 tests

Post by coderJeff »

aloberoger wrote:
pending an improvement or fixation or something else, it seems appropriate to point out this as a mistake
Unfortunate that there was no test for this in our test suite, otherwise probably would have noticed this source code compatibility break. The CONST versus CAST issue has been an on-going source of complication.
  • we have the CONST specifier, where we promise not to modify data, and we would like the compiler to let us know if we break that promise.
  • we have the CAST operator, where we change the data's type, possibly invoking conversion procedures, and we may or may not want to be warn/error on unsafe casting.
For concept, we probably want something like:
- ForceCast() - perform the cast and warn/error nothing
- SafeCast() - perform the cast with all type check warnings and errors
- Cast() - perform the cast, maybe with a few warnings only.

For comparison, standard c++ has it's own operators for this concept of selectively allowing or warning/error on casting: static_cast, reinterpret_cast, const_cast, and dynamic_cast. And MS has c++ extension safe_cast.

My efforts on const/cast in fbc-1.06 were to try and fix the really serious bugs, and then enable warnings only with '-w constness'. Obviously this change, and the bug as reported in the earlier post slipped through.

Another thought is maybe to have cast() allow const-ness change only, or data type change only, without warning/error. But if both are changed at same time through a single cast(), maybe give the programmer a warning.
fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: fb 1.07 tests

Post by fxm »

coderJeff wrote: And this (though you will get a warning if compiled with '-w constness' option):

Code: Select all

sub proc1( byref s as string )
end sub 
sub proc2( byref s as const string )
	proc1( cast(string, s) )
end sub
The less well-known Peek instruction is less impacted by such warnings:

Code: Select all

sub proc1( byref s as string )
end sub
sub proc2( byref s as const string )
   proc1( peek(string, @s) )
end sub
Maybe forgotten by the developers themselves!

But I agree to leave that in this state.
So everyone can decide how safe he is when he codes.

Code: Select all

Dim As Const Integer I = 0

*Cast(Integer Ptr, @I) = 1  '' CONST qualifier discarded
Poke Integer, @I, 2         '' CONST qualifier discarded
Peek(Integer, @I) = 3       '' No warning

Print I
fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: fb 1.07 tests

Post by fxm »

Another example where type conversion control is even more rigorous:

Code: Select all

Type UDT Extends Object
End Type

Dim As UDT u
Print @u
Print

'Print Cast(Integer Ptr, @u)                '' error 302: Casting derived UDT pointer to incompatible pointer type
Print Cast(Integer Ptr, Cast(Any Ptr, @u))  '' OK
Print @Peek(Integer, @u)                    '' OK
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fb 1.07 tests

Post by coderJeff »

fxm wrote:Maybe forgotten by the developers themselves!
Yes, It's true! I forget about peek & poke. Not since C64 & Atari days did I use peek & poke. Even in QB (TM) I preferred using ASM/C routines compiled in QLB/LIB routines rather than using peek & poke.
fxm
Moderator
Posts: 12131
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: fb 1.07 tests

Post by fxm »

fxm wrote: Maybe forgotten by the developers themselves!
But I agree to leave that in this state.
So everyone can decide how safe he is when he codes.
coderJeff wrote: Yes, It's true! I forget about peek & poke.
Forget Peek and Poke again very quickly!
This present behavior is fine for me.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fb 1.07 tests

Post by coderJeff »

aloberoger wrote:I still want to remember that with FB1.5 that was correct.

like this oder example
Constructor Comobject (ByRef varSrc As Const VARIANT) Export
vt = VT_EMPTY
InternalCopy (@Cast (VARIANT,varSrc))
End Constructor
I made a quick fix for this in Fix a cast(string, variable) issue that can cause fbc to segfault #177, so your code should work again.

I call it a "quick fix" because it fixes the examples given by you. Otherwise, I could probably spend another month testing tying to find other cases that might fail. And fbc needs some internal changes to progress the CONST vs CAST features more.

This fix is applied to both the master branch and fbc-1.07 branch. The fbc-1.07 branch is being used for upcoming 1.07.1 release.

Thanks again for testing and reporting the issues.
aloberoger
Posts: 507
Joined: Jan 13, 2009 19:23

Re: fb 1.07 tests

Post by aloberoger »

1.07 release is good but 1.07.1 release is expected

This is the first time I've created a library that can be used by both unicode and ansicode.
I chose to create two libraries one for UNICODE and one for ANSICODE
the GuisAU.bi file specifies it well by:
#Ifdef UNICODE
#Inclib "Guisu"
#Else
#Inclib "Guisa"
#endif

I think this is the best method for FB, because by creating a single library, the library will be very bulky and especially the executable resulting from a project using this library will be even larger, normal because FB (just like GC I believe) copy in the executable all the public functions contained in the library.

question technically simple can one during the process of compilation of an executable, know the public functions of a library that the project called and copy only those there in this project ?.



for the dynamic library, it seems to me wise that instead of creating two dlls, you only need one, but this time you have to rename the classes twice and twice the procedures of the bookstore code. not easy for a big project.
In fact Windows itself uses this method.




Without using a library, things are simpler, we define classes and functions only once except for xstring.
http://s000.tinyupload.com/?file_id=000 ... 2452462142
paul doe
Moderator
Posts: 1735
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: fb 1.07 tests

Post by paul doe »

coderJeff wrote:...
[*] we have the CONST specifier, where we promise not to modify data, and we would like the compiler to let us know if we break that promise.
...
Speaking of which: this won't work with delete and friends:

Code: Select all

/'
  A simple type to be aggregated
'/
type _
  Foo
  
  public:
    declare constructor()
    declare destructor()
    
    declare property _
      aProperty() as integer
    
  private:
    as integer _
      _aProperty
end type

constructor _
  Foo()
  
  _aProperty => -4
end constructor

destructor _
  Foo()
  
  ? "Foo::~Foo()"
end destructor

property _
  Foo.aProperty() _
  as integer
  
  return( _aProperty )
end property

/'
  Another type that aggregates an instance injected through the constructor.
  
  Now, the idea is to pass the instance either by pointer or by reference. The
  semantics used here is disposing the instance passed by pointer (to allow the
  syntax to new() up the object in the constructor) or by reference (to aggregate a
  reference to an existing instance).
  
  They need to be treated separately at destruction time, but I also want to expose it
  through a const pointer.
'/
type _
  Bar
  
  public:
    declare constructor( _
      byval as Foo ptr )
    declare constructor( _
      byref as const Foo )
    declare destructor()
    
    declare property _
      instance() as Foo const ptr
    
  private:
    declare constructor()
    
    as Foo ptr _
      _anInstance
    as boolean _
      _needsDisposing
end type

constructor _
  Bar()
end constructor

constructor _
  Bar( _
    byval aFoo as Foo ptr )
  
  _anInstance => aFoo
  _needsDisposing => true
end constructor

constructor _
  Bar( _
    byref aFoo as const Foo )
  
  _anInstance => cast( Foo ptr, @aFoo )
end constructor

destructor _
  Bar()
  
  if( _needsDisposing ) then
    delete( _anInstance )
  end if
  
  ? "Bar::~Bar()"
end destructor

property _
  Bar.instance() _
  as Foo const ptr
  
  return( _anInstance )
end property

/'
  Test case
'/
scope
  var _
    aFoo => Foo()
  
  /'
    Check to see if the semantics work as expected
  '/
  scope
    var _
      aBar => Bar( aFoo )
    
    ? "Using instance: " & aBar.instance->aProperty
  end scope
  
  scope
    var _
      anotherBar => Bar( new Foo() )
    
    ? "Using instance: " & anotherBar.instance->aProperty
  end scope
  
  /'
    All is well it seems...
  '/
  scope
    var _
      aBar => Bar( new Foo() )
    
    /'
      ...but this destroys the internal pointer, regardless of the const-ness
      of its qualifier.
    '/
    delete( aBar.instance )
  end scope
end scope

sleep()
Is this correct behavior? It seems to me that the delete operator should take into account the constness of its argument too...

If this can be corrected/added, it would be great... ;)
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fb 1.07 tests

Post by coderJeff »

aloberoger wrote:question technically simple can one during the process of compilation of an executable, know the public functions of a library that the project called and copy only those there in this project ?.
One method is to put each function in it's own module (file). Only the procedures needed will be included with the executable. This is the method that fb's run time library uses. Other suggestions can be found in the topic Creating Static lib with function level granularity. Though I have not tried.
"Without using a library, things are simpler, we define classes and functions only once except for xstring.
True. If the library is dependent on xstring's type at compile time, then need two separate libraries, or redesign and remove the dependency on xstring.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fb 1.07 tests

Post by coderJeff »

paul doe wrote:Is this correct behavior? It seems to me that the delete operator should take into account the constness of its argument too...
I think this is correct behaviour. Should see similar behaviour with allocate()/deallocate(). I think delete & deallocate are outside of the CONST promise, like there has to be someway to destroy/release CONST access data / pointers.

Code: Select all

type T
	__ as integer
end type

scope
	'' no CONSTs, can do anything 
	dim p as T ptr = new T
	p->__ = 1 '' OK
	delete p  '' OK
	p = 0     '' OK
end scope

scope
	'' promise not to change T when accessed through p	 
	dim p as const T ptr = new T
	p->__ = 1 '' error, promised not to change T
	delete p  '' OK, must allow p to be freed
	p = 0     '' OK
end scope

scope	
	'' promise not to change pointer p
	dim p as T const ptr = new T
	p->__ = 1 '' OK
	delete p  '' OK, must allow p to be freed
	p = 0     '' error, promised not to change p
end scope

scope
	'' promise not to change T accessed through p or pointer p
	dim p as const T const ptr = new T
	p->__ = 1 '' error, promised not to change T
	delete p  '' OK, must allow p to be freed
	p = 0     '' error, promised not to change p
end scope
Post Reply