"UNDEFINED REFERENCE" SLIPPING THROUGH?

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

"UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 17, 2017 22:28

After half an hour chasing a strange "undefined reference" error, I found something interesting, which I consider at least undesired compiler behaviour.

Consider the following code:

Code: Select all

type A extends object
   i as integer
   declare constructor
end type

type B extends A
end type

type C extends object
   myA(0) as A
   'myB as B
end type

end
If you copy and compile, it will run just fine. Now uncomment the line 'myB as B in type C and compile again. ERROR!

However, the problem is NOT the definition myB as B. It is the fact that type A has a constructor declare but without an actual constructor!

I was going crazy hunting my include files and commenting in and out the lines similar to those in type C in the example code. Shouldn't the compiler handle this differently? I noticed this kind of error before when declaring a constructor but without constructor body. But as a project grows this type of error can be very hard to trace.

I'd prefer the compiler to halt at the declare constructor line and give a proper message, something like "constructor not defined". I wouldn't go as far as calling this a compiler bug, although allowing the code to run in certain circumstances comes close. It should either halt without making exceptions, or ignore the constructor declaration altogether.
St_W
Posts: 1166
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby St_W » Nov 18, 2017 0:56

It may seem strange to you, but the compiler's behaving exactly as expected. It is definitely no compiler bug or compiler problem. In fact the compiler cannot know about a missing implementation of a constructor because you are free to implement that in any module you like and compile them fully independent from each other. What you do by declaring a method (or a constructor in this case) is to tell the compiler that there exists such a method and how to call it. When the method is not part of the same compilation unit the method reference has to be resolved by the linker (not the compiler). And of course the linker will complain when some module requests a method while there is no (other) module providing it.
fxm
Posts: 7477
Joined: Apr 22, 2009 12:46
Location: Paris suburb, FRANCE

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby fxm » Nov 18, 2017 7:01

Code: Select all

type A
   i as integer
   declare constructor
end type

type B extends A
end type

type C
   myA as A
   myB as B
end type

When declaring "myA as A" in "C", a "A" default constructor is already declared, so that the compiler has nothing to add for the "myA" construction.

When declaring "myB as B" in "C", no default constructor is declared in "B".
As "A" (the base of "B") has a default constructor declared, the compiler must add a hidden default constructor to "B" (to call the declared "A" constructor).
Therefore the complete code provided by the compiler for defining "A" and "B" becomes similar to this:

Code: Select all

type A
   i as integer
   declare constructor
end type

type B extends A
   declare constructor  '' hidden
end type
constructor B           '' hidden
   base()               '' hidden
end constructor         '' hidden
which induces the same error than the 1st code.
Munair
Posts: 358
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 18, 2017 7:49

OK, I understand. I encountered this before, but forgot about the details of this particular situation.
St_W wrote:And of course the linker will complain when some module requests a method while there is no (other) module providing it.

But that's the problem -- although explained why by fxm -- if you comment out the line in type C the linker will not complain, making it hard to trace the problem.

Anyway, good that I ran into this. It would be possible for a an IDE or RAD environment to check and catch these kind of things before feeding the code to the compiler and linker.
paul doe
Posts: 177
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby paul doe » Nov 18, 2017 14:34

.
Last edited by paul doe on Nov 18, 2017 20:48, edited 1 time in total.
Munair
Posts: 358
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 18, 2017 15:25

paul doe wrote:
Munair wrote:Anyway, good that I ran into this. It would be possible for a an IDE or RAD environment to check and catch these kind of things before feeding the code to the compiler and linker.

There is nothing to catch, as there is no error here, just you being careless.
Of course I was careless. But EVERY programmer has been careless in their programming career now and then. There's no programmer who never makes (stupid) mistakes. And the larger a project becomes, the longer it usually takes to track things down.

Programming tools, IDE, RAD and otherwise, can make things easier and can track inconsistencies more quickly. In this particular case the code could be checked against incomplete declares/definitions in the same process as finding unused variables.
paul doe wrote:And the correct way to write the example you gave would be
You must be joking.
fxm
Posts: 7477
Joined: Apr 22, 2009 12:46
Location: Paris suburb, FRANCE

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby fxm » Nov 18, 2017 15:56

Example for more explaining:

Code: Select all

Type UDT Extends Object
  Dim As Integer I
  Declare Constructor ()
  Declare Sub s ()
  Declare Function f () As Integer
  Declare Property p () As Integer
  Declare Property p (Byval As Integer)
  Declare Destructor ()
  Declare Virtual Sub vs ()
End Type
    undefined reference to `UDT::VS()@4'
You can declare any non-virtual member procedure (and which does not override a base procedure) without defining the procedure body as long as the procedure is not called (explicitly or implicitly) by the code.

On the contrary, if you declare any virtual member procedure (or which overrides a base procedure), you must always define the corresponding procedure body, because even if none instance is constructed, the compiler must always create and fill the type's virtual table (vtable) containing the static address of the virtual (or overriding) procedure.
Then, when constructing an instance of such a type, the compiler will only have to add as the first data field member the virtual pointer (vptr) allowing the access to this predefined vtable.
Last edited by fxm on Nov 18, 2017 20:01, edited 1 time in total.
paul doe
Posts: 177
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby paul doe » Nov 18, 2017 16:08

.
Last edited by paul doe on Nov 18, 2017 20:48, edited 1 time in total.
Munair
Posts: 358
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 18, 2017 16:12

paul doe wrote:What I was trying to tell you was that it isn't a compiler error...
I didn't say it was a compiler error. I said 'undesired compiler behaviour.'
paul doe wrote:Why? Your example doesn't compile.
Correction, it DOES compile, just as I stated. Apparently you didn't try. The problem is uncommenting the line in type C. Only then the mistake becomes apparent. And I already hinted to the fact that the problem is the constructor declaration in type A. ;)
Last edited by Munair on Nov 18, 2017 16:49, edited 2 times in total.
paul doe
Posts: 177
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby paul doe » Nov 18, 2017 16:14

.
Last edited by paul doe on Nov 18, 2017 20:48, edited 1 time in total.
Munair
Posts: 358
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 18, 2017 16:16

fxm wrote:You can declare any non-virtual member procedure without defining the procedure body as long as the procedure is not called (explicitly or implicitly) by the code.
Yes, I noticed. Thank you for the thorough explanation.
Munair
Posts: 358
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 18, 2017 16:22

paul doe wrote:
Munair wrote:
paul doe wrote:Why? Your example doesn't compile.
Correction, it DOES compile, just as I stated. Apparently you didn't try. The problem is uncommenting the line in type C. Only then the mistake becomes apparent.

And apparently you're just trying to p*ss me off, for the example I gave you was actually your 'problem' code.
If you had taken the time to actually read my first post, you would have realized that I already knew the cause of the problem (it was even underlined). Naturally, either removing the dangling declaration or providing the constructor body would have solved it. But no offence and thanks for reminding me anyway.
paul doe
Posts: 177
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby paul doe » Nov 18, 2017 16:26

.
Last edited by paul doe on Nov 18, 2017 20:49, edited 1 time in total.
Munair
Posts: 358
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby Munair » Nov 18, 2017 16:33

paul doe wrote:
Munair wrote:If you had taken the time to actually read my first post, you would have realized that I already knew the cause of the problem. So naturally, either removing the dangling declaration or providing the constructor body would have solved it. But thanks for reminding me anyway.

And if you've actually taken the time to read what I wrote you would see that's the same explanation fmx gave you but written in a more succint way. Nothing more. I didn't imply that you were stupid, or that your code sucks, only how the compiler works. JFC what's with the attitude, then?
I read your post from top to bottom. ;) My problem was not how to solve it. My problem was that the compiler and linker didn't complain with my example code (which is what the thread title implies). It runs just fine, even though no constructor body was provided. fxm explained why.
Last edited by Munair on Nov 18, 2017 16:38, edited 1 time in total.
fxm
Posts: 7477
Joined: Apr 22, 2009 12:46
Location: Paris suburb, FRANCE

Re: "UNDEFINED REFERENCE" SLIPPING THROUGH?

Postby fxm » Nov 18, 2017 16:34

Me, I had well understood that Munair had clearly identified the problem.
I only added information trying to explain this internal behavior of the compiler.

Return to “General”

Who is online

Users browsing this forum: Exabot [Bot] and 5 guests