Skip to main content

Compile and uncompilable function bug?


I think I found a bug, but I still have MMA version 11.0.1 installed. Can somebody please check if this persists in the latest version?


When I compile this function:


cf = Compile[{{n, _Integer}},
Module[{good},
good = True;
If[DuplicateFreeQ[{}] && n == 15, good = False];

good
]
];

The result changes once the condition is met:


cf[14]
cf[15]
cf[14]
(* True *)
(* False *)

(* False *)

Here it is immaterial what list is given to DuplicateFreeQ.


Addendum 1


As @Jason B. and @Michael E2 pointed out, the important thing is that DuplicateFreeQ cannot be compiled. Thus, a more general example is


fun := True; (* use := so fun cannot be compiled *)
With[{cf = Compile[{{n, _Integer}},
Module[{xyz},
xyz = True;
If[fun && n == 15, xyz = False];

xyz
]
]},
{cf[14], cf[15], cf[14]}
]
(* {True, False, False} *)

Now, @Michael E2 wrote that it seems as if



there is a runtime environment in the WVM connected to cf, in which the assignment good = False leaks out in some form and is stored across calls to cf.




Here is some evidence for that, I think:



  1. Quit the kernel.

  2. ?Global`xyz* gives a warning that there is no xyz defined.

  3. Evaluate


With[{cf = Compile[{{n, _Integer}}, Module[{xyz}, xyz = True; If[n == 15, xyz = False]; xyz]]}, {cf[14], cf[15], cf[14]}] (* {True, False, True} *)


as it should be.





  1. ?Global`xyz* shows that a Global`xyz has been defined.




  2. Evaluate the code at the beginning of Addendum 1, giving the wrong result {True, False, False}, and you find that Global`xyz as well as Global`xyz$ are defined, where Global`xyz$ has the attribute Temporary.






Comments