Crash in compiled mode when passing Null as parameter

v18R2, Mac

Method test:
Crash4D(Null)

Method Crash4D:
C_POINTER($1;$p)
$p:=$1

Interpreted, works fine; and just before the assignment, both $p and $1 show as nil in the debugger.
Compiled (compiles without complaint, no warnings), crashes on assignment.

Bug?

Jeremy

Hi Jeremy

This is absolut normal behaviour.

In interpreted mode you can switch any type of a variable anytime.
Too only in interpreted mode your method-locally declaration C_POINTER($1;$p)
predefine the type to pointer which has is as default nil.
But after this locally interpreted declaration you can switch anytime the type
with $ptr:=$anyOtherVarType
This is only in interpreted mode not per default a must be a type-error.

When you compile your sources, than the types get fixed by the compiler-directives.
Commands like “C_anything” not exist in the compiled result.
This declarations gone in compiled and replaced by fixed-types
(=always constant type, sorry my english…but with a little bit of phantasy you understand what i mean)
In Compiled-Mode it is always a error when you switch types,
but it is interesting this not shows a error message
instead it crashed when try to let a pointer let be null (instead of pointing to anything).

Null can only apply to a C_OBJECT or to C_VARIANT

Lutz

Lutz,

I understand what you are saying, but I think, with respect, that your assertion that “Null can only apply to a C_OBJECT or C_VARIANT” is not correct: see https://doc.4d.com/4Dv18R2/4D/18-R2/Null.301-4802769.en.html.

Also, this code runs just fine, interpreted or compiled:

C_POINTER($p)
$p:=Null

The crash happens only when Null is passed as a parameter.

Jeremy

1 Like

Crashing is always not good.
When i not know this is a bug or not a bug,
and you too not,
than we can wait until we get any qualified complete statement
to that from 4D or any 4D-Developer.

I think it is not wrong when you make a bugreport for that,
to get any statement
or to get full bufix
or to get small bugfix only a errorMessage instead of crash.


Pointers and Parameters, that is a very special kind
which can not so easy directly compare with behaviour of OtherTypes
and with normalVariables(not parameters).

Think about a Pointer can only point on something or be Nil,
nothing other the status of a pointer-variable can have.

When assign a Null to a Pointer it is like
assign Nil (or do this with CLEAR VARIABLE),
Nil is the init status of a pointer which still not point to something.

That is different to, only for example, a C_OBJECT or a C_COLLECTION
which init status is Null
and when not Null than it is a referece to a object or collection.

C_POINTER($ptr)
$ptr:=Null  // translated to Nil

C_LONGINT($longint)
$longint:=12.34  // translated to 12

C_OBJECT($obj)
$obj:=Null

C_COLLECTION($col)
$col:=Null

Using Parameters is not totally the same like to assign with :=

To have a caller like this (and myMethod has only pointer parameters)
it not worked to have instead $ptr3 a constant Null (like to advice $3 is not needed/defined)

$ptrResult:=myMethod($ptr1; $ptr2; Null; $ptr4)

To beware from error message or crash, it is better to let third parameter in call Nil and not Null.
Here are two routines what always needed in different situations:

  // PM: "zGetNilPtr"
  // This method only returns a constant nil pointer

C_POINTER($ptr;$0)

$0:=$ptr

  // - EOF -
  // PM: "zGetFixType"
  // This method gives you always wished type (save to use a fix type parameter)
  // Example call: zGetFixType (Null;Is pointer) // -> Nil

C_VARIANT($result;$0)
C_VARIANT($src;$1)
C_LONGINT($type;$2)

If (Count parameters>0)
	$src:=$1
	If (Count parameters>1)
		$type:=$2
	Else 
		$type:=Is text
	End if 
Else 
	$src:=""
	$type:=Is text
End if 

$result:=OB Get(New object("x";$src);"x";$type)

$0:=$result

  // - EOF -

Use case example “zGetNilPtr”

$obj:=New object
$obj.ptr1:=->[person]firstname
$obj.ptr2:=->[person]lastname
$obj.ptr3:=zGetNilPtr
$obj.ptr4:=->[company]name
$ptrResult:=myMethod($obj.ptr1; $obj.ptr2; $obj.ptr3; $obj.ptr4)

Use case example “zGetFixType”

$obj:=New object
$obj.ptr1:=->[person]firstname
$obj.ptr2:=->[person]lastname
$obj.ptr3:=Null
$obj.ptr4:=->[company]name
$ptrResult:=myMethod(zGetFixType ($obj.ptr1;Is pointer); zGetFixType ($obj.ptr2;Is pointer); zGetFixType ($obj.ptr3;Is pointer); zGetFixType ($obj.ptr4;Is pointer))

More simple to read, but not a realistic example of a needed to do it this way

$ptrResult:=myMethod($ptr1; $ptr2; zGetFixType(Null;Is pointer); $ptr4)

When only a fix Nil is needed use “zGetNilPtr”

$ptrResult:=myMethod($ptr1; $ptr2; zGetNilPtr; $ptr4)

Do not forget, i am just discuss about it and give some tipps maybe it helps anyway,
because i can+will not make the final decision “bug” or “not a bug”
and too not again decide “it would maybe normal expected behaviour”.
I think at minimum 4D needs to write this more clear in documentation
(what is possible, what did not work, what is absolutly forbidden when you want beware from crash, and lastNotLeast a detailed explanation about the always question “Why it must be so?”)

Lutz

Lutz,

I think we can be fairly sure that anything which causes an immediate crash is a bug somewhere.

You’re correct in saying there’s an easy solution: replace

Crash4D(Null)

with

C_Pointer($nil)
Crash4D($nil)

and that is what I’ve done. I shouldn’t have had to spend the best part of a day tracking it down because was crashing, though.

Do you have any idea how I can report the bug? I’m not a Partner and the old ways don’t seem to work any more.

Jeremy

Sorry this i did not know
where or how to report a bug
when not a 4D partner

It is possible,
but i did it always only as partner.

With a partner login in this forum
you see (for example in beta-forum)
two buttons right top “+ New Bug” and “+ New Thema”.
With this it is possible to post direct here in forum a bug
Same way doing normal forum post,
but with stamp bug and with optional a example-zip attached when needed.

Too as partner i use https://taow.4d.com
when i want more a statement from 4D first
or some tipps or any other possible workarounds
or some discuss about why it is a important problem in my use case.

And there exist too a 4D-URL https://bugs.4d.com/index.htm

When i had more time any day in the future
i do the report-bug job for you
when until then you not find a way to do it self.
But first i must do all my own open not done jobs.

Maybe other people can help you with info how to report bug.

Hello Jeremy,

You can report your bug via TAOW if you are not partner by using the top green button “Report a bug without assistance”:

Regards,

Thanks, Omar. I see this, but I assume it’s the same. I’ll give it a go.

Jeremy

Jeremy,
A pointer can not be null. It’s nonassigned values is nil. 4D has engineered the comparison operator to equate nil with null when testing a value, which is a huge convenience for us in programming, but that does not make null and nil the same thing.

Your example work interpreted because 4D makes the adjustment in variable type on the fly. It fails when compiled because null is not a pointer.

If you are going to use nil pointers you have to create it.

	C_POINTER($nil)
	
	If ($nil=Null)
		Crash4D($nil)  //  no crash
	End if
1 Like

Kirk,

The documentation for Null (https://doc.4d.com/4Dv18/4D/18/Null.301-4504873.en.html) shows

So it should be perfectly permissible to assign Null to a pointer; and indeed it is:

C_POINTER($nil)
$nil:=Null

works fine, interpreted or complied. The crash occurs only when Null is passed as a parameter and then assigned to a local, and I don’t see anything in any documentation to suggest that there should be a difference between direct assignment and passage as a parameter.

Even if what I’m doing should fail, it certainly shouldn’t crash. I’d have thought, on your argument, that the compiler should complain (at least, warn) about the fact that Null has been passed as a parameter to a method expecting a pointer.

Jeremy