Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jiangyilism opened this issue Sep 1, 2022 · 10 comments
Open

Comments

@jiangyilism
Copy link
Contributor

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
Copy link
Contributor Author

For reference, #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.

@ferdymercury
Copy link
Collaborator

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

@jiangyilism
Copy link
Contributor Author

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?

@Axel-Naumann
Copy link
Member

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
Copy link
Member

Axel-Naumann commented Sep 2, 2022

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!

@jiangyilism
Copy link
Contributor Author

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.

@pcanal
Copy link
Member

pcanal commented Sep 2, 2022

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)

@Axel-Naumann
Copy link
Member

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 ?

@jiangyilism
Copy link
Contributor Author

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?)

@Axel-Naumann
Copy link
Member

@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?

@dpiparo dpiparo assigned pcanal, dpiparo and vepadulano and unassigned Axel-Naumann Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants