root icon indicating copy to clipboard operation
root copied to clipboard

[cling] script/library support entry function independent of filename

Open jiangyilism opened this issue 3 years ago • 10 comments

Is your feature request related to a problem? Please describe.

In cling cmd prompt, .x, .X meta commands loads a .C script then invoke a function with the same name as the script file (stripped extension). Every time the filename changes the entry function name needs to be changed too. This is not user friendly, or even error prone.

P.S. In interpreter/cling/lib/MetaProcessor/MetaSema.cpp , there is a comment about plan to enabling using __main__ as a filename independent entry function name. However identifier with two underscores is reserved by c++ standard (https://en.cppreference.com/w/cpp/language/identifiers).

Describe the solution you'd like

A filename independent entry function like clingmain, clingstart, clingrun, cling_on_load, cling_on_x... etc. Or function attribute like [[cling::on_load]] int any_func_name(char c, int a) {...} to let cling call any_func_name on meta cmd .x. A [[cling::on_unload]] can be useful too, though not directly related to this feature request.

jiangyilism avatar Sep 01 '22 09:09 jiangyilism

For reference, https://github.com/root-project/root/pull/11262 has a commit to support entry function not identical to filename. If the file is a hidden file that name starts with a dot, cling executes the function name which is same as file name but without preceding dot.

jiangyilism avatar Sep 01 '22 09:09 jiangyilism

Wouldn't an unnamed macro do the job? See attached file. The filename can be changed without having to 'rename' the main function.

test.C.zip

ferdymercury avatar Sep 01 '22 10:09 ferdymercury

Unnamed macro is a root feature. standalone cling does not support it.

In a cling test case root/interpreter/cling/test/Prompt/MetaProcessor/Macros.C, it is stated that "This test should test the unnamed macro support once it is moved in cling." So cling does not support it yet. Personally I would suggest cling to never support it unless future c++ standard supports similar construct. https://root-forum.cern.ch/t/what-is-the-difference-between-unnamed-macro-and-named-macro/30455 discouraged usage of unnamed macro in root too though I do not know if it is cling's current position. @Axel-Naumann what is cling's future plan on unnamed macro?

jiangyilism avatar Sep 01 '22 11:09 jiangyilism

No plans. But whatever the plans currently are will need to be adjusted if and once the clang patch for statements at global scope is in, as that changes the equation dramatically.

Axel-Naumann avatar Sep 02 '22 05:09 Axel-Naumann

However identifier with two underscores is reserved by c++ standard

They are reserved for implementers. Cling is an implementation, so we can totally do that :-) We actually have to do that, to avoid misinterpretation of an existing function. The attribute seems like a good alternative, though!

Axel-Naumann avatar Sep 02 '22 05:09 Axel-Naumann

Do you meaning this patch? [clang-repl] Support statements on global scope in incremental mode It looks almost identical to unnamed macro support. So I assumed clang-repl (and later cling) will have that feature soon. However, both "on load" feature implemented with that patch or unnamed macro bring a problem that the script file is not a valid c++ source file anymore so a compiler, not an interpreter like cling, cannot compile it. While my proposed approaches do not have this limitation. But of course, we can #include "a_valid_cxx_file.cpp" in a .C script file containing unnamed macro for "on load". Just a little indirect.

jiangyilism avatar Sep 02 '22 09:09 jiangyilism

As a side note, C++ already has a notion of onload so another option could be for the user to simply use:

int anyfunction( .... ) { ... }
int execthefunctonload = anyfunction();

(and on-unload can also be done (using a class destructor for example) but requires a bit more scaffolding)

pcanal avatar Sep 02 '22 12:09 pcanal

I was not advocating for unnamed macros as alternative to what you propose here, @jiangyilism .

I think @pcanal 's proposal qualifies as a (technically correct) "hack" :-) We could indeed use __attribute__((constructor)) as the attribute - but that calls the function as part of static initialization, not after static initialization like main() or the current function-name-as-file-name, and the file would have to be loaded through .L not .x. Would that be good enough, @jiangyilism ?

Axel-Naumann avatar Sep 02 '22 13:09 Axel-Naumann

Using .L or __attribute__((constructor)) or static initialization are good alternatives.

However that does not improve usability of .x . As mentioned in the first post, entry function still need renaming when file get renamed. Also we get function redefinition error when .x or .L two scripts with same name. For example dir0/test.C and dir1/dir2/test.C (with completely different content) cannot both define their test(...) entry functions. They cannot be put into different namespaces either otherwise cling does not recognize them as entry functions.

However, __main__(...) approach suffers from multiple definitions too. Unless cling unloads/drops symbol __main__ after executing it (btw. In this case will static variables of __main__ get destructed too?)

jiangyilism avatar Sep 02 '22 14:09 jiangyilism

@jiangyilism I am proposing to change the behavior of .x to not complain about a missing function filename() if there is a function marked with __attribute__((constructor)). How is that not a solution to this issue?

Axel-Naumann avatar Sep 20 '22 08:09 Axel-Naumann