Unexpected behaviour of type arrays

New to FreeBASIC? Post your questions here.
Post Reply
Pjbonovox
Posts: 2
Joined: Apr 22, 2019 10:01

Unexpected behaviour of type arrays

Post by Pjbonovox »

Greatly simplified, but for the output I'd expect 10, but get 0. What's the best way to achieve the desired outcome?

Code: Select all

TYPE athing
  x AS INTEGER
END TYPE

TYPE collection
  thing AS athing
END TYPE

DIM somethings(10) as athing
DIM manythings(10) as collection
  
somethings(0).x = 10
manythings(0) = somethings(0)

PRINT manythings(0).x

Thanks! Phil.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Unexpected behaviour of type arrays

Post by badidea »

I get a compile error:
test.bas(13) error 180: Invalid assignment/conversion in 'manythings(0) = somethings(0)'
test.bas(15) error 18: Element not defined, x in 'PRINT manythings(0).x'


This works, but I am not sure that this is what you want:

Code: Select all

TYPE athing
  x AS INTEGER
END TYPE

TYPE collection
  thing AS athing
END TYPE

DIM somethings(10) as athing
DIM manythings(10) as collection
 
somethings(0).x = 10
manythings(0).thing = somethings(0)

PRINT manythings(0).thing.x
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Unexpected behaviour of type arrays

Post by paul doe »

Indeed, as badidea points out, you're just missing an additional indexing operation. Otherwise, the semantics of the original expression is to copy-construct/assign two objects of different types (and the copy-constructor/assignment operator is undefined for both of them).

You can define operators to do those tasks, but you can't overload the '.' (scope resolution operator) in FreeBasic, just the '->' (pointer dereference operator). The code that does what you want is thus:

Code: Select all

TYPE athing
  x AS INTEGER
END TYPE

TYPE collection
  thing AS athing
  
  declare operator _
    let( _
      byref as athing )
  declare operator _
    cast() as athing
END TYPE

operator _
  collection.let( _
    byref rhs as athing )
  
  thing => rhs
end operator

operator _
  collection.cast() _
  as athing
  
  return( thing )
end operator

operator _
  ->( _
    byref lhs as collection ) _
  as athing
  
  return( lhs.thing )
end operator

DIM somethings(10) as athing
DIM manythings(10) as collection
 
somethings(0).x = 10
manythings(0) = somethings(0)

? manythings( 0 )->x 

sleep()
Changing the semantics of operators is not what I'd recommend, though. Not to mention that the 'collection' type is totally superfluous in this example, but I imagine that this is part of a larger type...
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Unexpected behaviour of type arrays

Post by fxm »

For information on the '->' operator overloading and one classic use case, you can also read the article:
How to Overload the Operator '->' (ptr to member access) and Build a Smart Pointer in FB
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Unexpected behaviour of type arrays

Post by fxm »

Referring to the above example of paul doe, defining a cast operator is useless in this use case.
By cons, it would allow the following syntax:
? cast(athing, manythings(0)).x
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Unexpected behaviour of type arrays

Post by Munair »

You'd get 10 if you'd assign the right types:

Code: Select all

TYPE athing
  x AS INTEGER
END TYPE

TYPE collection
  thing AS athing
END TYPE

DIM somethings(10) as athing
DIM manythings(10) as collection
 
somethings(0).x = 10
manythings(0).thing = somethings(0)

PRINT manythings(0).thing.x

Is there a technical reason for assigning somethings(0) to manythings(0) instead of manythings(0).thing?
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Unexpected behaviour of type arrays

Post by fxm »

Exactly the above badidea's post (first response).
The others are digressions.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Unexpected behaviour of type arrays

Post by badidea »

fxm wrote:Exactly the above badidea's post (first response).
"Great minds think alike?" or "fools seldom differ?” :-)

Crazy example of nested types:

Code: Select all

const MAX_SONGS = 30 'per album
const MAX_ALBUMS = 200 'per collection
const MAX_COLLECTIONS = 50

type song_type
	dim as string*200 artist
	dim as string*200 title
	dim as ulong releaseYear
	dim as ulong track
	dim as ulong side
end type

type album_type
	dim as string*200 title
	dim as ulong numSongs
	dim as song_type song(MAX_SONGS-1)
end type

type collection_type
	dim as string*200 owner
	dim as ulong numAlbums
	dim as album_type album(MAX_ALBUMS-1)
end type

dim as ulong numCollections
dim shared as collection_type collection(MAX_COLLECTIONS-1)

numCollections = 1
collection(0).owner = "badidea"
collection(0).numAlbums = 1
collection(0).album(0).title = "ABBA Arival"
collection(0).album(0).numSongs = 2
collection(0).album(0).song(0) = type("ABBA", "Dancing Queen", 1976, 2, 1)
collection(0).album(0).song(1) = type("ABBA", "Money, Money, Money", 1976, 1, 2)
numCollections = 2
collection(1).owner = "Pjbonovox"
collection(1).numAlbums = 1
collection(1).album(0) = collection(0).album(0) 'copy album

'show all, crazy use of nexted with :-)
for iCollection as integer = 0 to numCollections-1
	with collection(iCollection)
		print trim(.owner); " - "; .numAlbums
		for iAlbum as integer = 0 to .numAlbums-1
			with .album(iAlbum)
				print trim(.title); " - "; .numSongs
				for iSong as integer = 0 to .numSongs-1
					with .song(iSong)
						print trim(.artist); " - "; trim(.title); " - ";  .releaseYear; " - ";  .track; " - ";  .side
					end with
				next
			end with
		next
	end with
next
Variable-length arrays and subs/functions to add/remove/copy/move items would be better, but I wanted to keep the example short.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Unexpected behaviour of type arrays

Post by fxm »

Can be further shortened!

Code: Select all

numCollections = 1
'collection(0).owner = "badidea"
'collection(0).numAlbums = 1
'collection(0).album(0).title = "ABBA Arival"
'collection(0).album(0).numSongs = 2
'collection(0).album(0).song(0) = type("ABBA", "Dancing Queen", 1976, 2, 1)
'collection(0).album(0).song(1) = type("ABBA", "Money, Money, Money", 1976, 1, 2)
collection(0) = type("badidea", 1, {type<album_type>("ABBA Arival", 2, {type<song_type>("ABBA", "Dancing Queen", 1976, 2, 1), type<song_type>("ABBA", "Money, Money, Money", 1976, 1, 2)})})
numCollections = 2
'collection(1).owner = "Pjbonovox"
'collection(1).numAlbums = 1
'collection(1).album(0) = collection(0).album(0) 'copy album
collection(1) = type("Pjbonovox", 1, {collection(0).album(0)})
Post Reply