# Mathematica8 can compile this function but Mathematica 9 can't if I set CompilationTarget -> “C”

Following code worked on Mathematica 8, but in Mathematica 9 it can't be compiled, it return this message

CompiledFunction::cflist: Nontensor object generated; proceeding with uncompiled evaluation. >>

How can I fix this?

Clear[cf1];
cf1 = Compile[{},
Module[{s = 0.0},
Do[
If[s > 15, Print@i; Break[]];
s = s + 1.0/i;
, {i, 10^7}];
], CompilationTarget -> "C"];

cf1[]

-
You function does not return anything and it uses a Print which is never a good idea inside a compiled function. Removing the Print fixed your problem here. – halirutan Jun 2 '13 at 18:23
Although I haven't tried it, I'm certain that @halirutan is correct so, probably, V9 is doing a better job of flagging uncompilable functions In addition, I'd point out that I don't see any output coming from your function. Perhaps, you should replace Do with Table and remove the semi-colon from the final statement inside the loop. – Mark McClure Jun 2 '13 at 18:31
Regardless of the fact that the use of Print is not optimal, this does seem to be a bug in the version 9 VM or CCodeGenerator package. The same bytecode is generated by versions 8 and 9, but the interpretation of it by version 9 seems to be incorrect. It's not clear to me why this only shows up with CompilationTarget -> "C". – Oleksandr R. Jun 2 '13 at 18:52
@OleksandrR. But Print, so far as I know, is not compilable. It certainly doesn't appear in the list CompileCompilerFunctions[] and CompilePrint[cf1] reveals a callback to MainEvaluate. – Mark McClure Jun 2 '13 at 19:48
@MarkMcClure that's correct, but irrelevant to the situation except in as much as it might expose a bug that would remain hidden otherwise (cf. this). The presence of a call back into the interpreter certainly should not trigger an exception that leads to re-evaluation of the entire function, and especially not in a version-specific way and only for a particular compilation target. I think the most likely situation is that version 9 produces an incorrect translation of the bytecode to C. – Oleksandr R. Jun 2 '13 at 20:11

In version 8, the callback into the interpreter (also known as MainEvaluate or WolframCompileLibrary_Functions->evaluateFunctionExpression) looks like

Function[{iCompile$1}, Block[{i = iCompile$1}, {Print[i], i}]][register]


where register is the (integer, scalar) register that contains the value of i. This looks correct to me, although I'll admit that I don't understand the reason for translating Print[i] into {Print[i], i}.

In version 9, however, it takes the incorrect form:

Function[{}, Print[i]][register]


Since this is obviously wrong (which one can also see from the fact that i is printed literally), the question might as well ask why it works at all, even without translating the bytecode to C. The reason is that the bytecode contains the instruction

{46, Function[{}, Print[i]], {i, 2, 0, 3, Block}, 6, 0, 17}


in both versions, and it is the responsibility of the execution host (either the VM, or the CCodeGenerator package in case of translation to C) to interpret this into a valid call. Clearly, the VM is capable of doing this in both version 8 and version 9, which is not surprising since I don't believe that any changes were made to the VM in version 9. Thus, although this problem resembles the one discussed in this question, I don't think the bugs are actually related.

However, the CCodeGenerator package was changed in version 9, and appears to have become broken in this respect. In conclusion: it's a bug--please report it.

Since bugs may not be fixed in a publicly available release for some time, you can work around the issue simply by removing the reference to Print and returning the value of i instead:

Clear[cf1];
cf1 = Compile[{},
Module[{s = 0.0},
Do[If[s > 15, Return[i]]; s = s + 1.0/i, {i, 10^7}]
], CompilationTarget -> "C"
];

cf1[]

-