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
Extension: allow recursive macros #65851
base: main
Are you sure you want to change the base?
Conversation
Compiler extensions are best proposed through a RFC, ie a discourse post here: https://discourse.llvm.org/c/clang/6 Explaining the motivation for the feature, which the pr description already does a good job. There are questions about the name, theorically this is an identifier that c and c++ committees may want to use in the future. You should also consider whether this needs extensions flags and extension warnings. Is this something you plan to propose to other compilers? Standardization? It does sound like an interesting feature though, and the implementation appear reasonable. You should also consider recursion limits and other edge cases. In terms of the code itself, it's missing unit tests |
Yes, the name define2 is a placeholder, but the more I look at it, the more it looks appropriate
Maybe, but I dont think standard committee will consider the proposal without reference implementation(if its not a modules ofc)) and, in case of preprocessor, usage in 'real world'
i will research how to do it in llvm |
How would you deal with the issue of infinite loops? The following program: #define2 boom(X) boom(X)
boom(0) Will continue to infinitely(?) consume memory until it is killed, either by the user or due to running out of memory on the system |
As for other similar things like templates/inheriting/includes must be recursion depth limit, but in this case "MacroInfo" required to be 40 bytes(and code dont says for what, but i expect some runtime sized structs etc), so now i think how to do it better |
I'd like to echo what @cor3ntin suggested above -- this needs an RFC to be posted to Discourse so the community is aware of the potential new language extension. We have a set of criteria for what we're looking for in such an RFC: https://clang.llvm.org/get_involved.html#criteria -- having the patch is a great start though as you can link to the patch from the RFC to give people a more concrete idea of what's being proposed.
I'm not certain it's a particularly good name in terms of standardization as there's no way for users to distinguish between
There's a chicken-and-egg problem. The committee wants to see implementation experience and the community wants to see support from the committee for larger ideas (we don't really want to add language extensions over objections from a standards committee unless there's sufficiently compelling reasons to do so). I have not yet had the chance to review the code changes, but I do have some concerns at a high-level. Preprocessor language extensions are a bit difficult because of adoption issues. Unless other implementations also implement the same extension, a significant number of folks wind up needing to use preprocessor conditionals to skip the new feature and write fallback code so their macros remain portable, but once you write that fallback code, you no longer need the extension code in the first place. When writing your RFC, it would be good to mention whether you've been talking to other implementations and what their thoughts, opinions, and concerns are. It's also worth noting that you can write recursive macros in C, though it's not easy without use of a macro library like P99. |
I will create it soon
I think this should be determined during the discussion, another possible name is
Yes, thats problem, every extension even not in preprocessor have same problems, but I think there are many projects now which use only clang and if people like the idea possibly it will be gcc extension too
As far as I know, the maximum that can be done is to code-generate many very difficult-to-understand constructs that allow you to repeat your code up to N times, creating the illusion of recursion and I would like to fix it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A RFC is in progress here
https://discourse.llvm.org/t/rfc-allow-recursive-macros-as-extension/73401
10b7329
to
49d7fa2
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
Version with #define reverse(head, ...) __VA_OPT__(__THIS_MACRO__(__VA_ARGS__) , ) head
|
Add 'define2' directive, which works as 'define', but allows recursive macros
Motivation:
Nlohmann json:
https://github.com/nlohmann/json/blob/836b7beca4b62e2a99465edef44066b7401fd704/include/nlohmann/detail/macro_scope.hpp#L320
boost preprocessor:
https://github.com/boostorg/preprocessor/blob/develop/include/boost/preprocessor/seq/detail/limits/split_1024.hpp
boost pfr:
(codegen)
https://github.com/boostorg/pfr/blob/develop/include/boost/pfr/detail/core17_generated.hpp
data_parallel_vector:
https://github.com/kelbon/AnyAny/blob/4b056be2b6cbcfa1a407f7ee75279af414e390e4/include/anyany/noexport/data_parallel_vector_details.hpp#L62
Its easily may be used for what 'magic enum' do, in many cases it can replace reflection ( because many who want reflection actually just want to create a JSON schema without specifying names twice )
C++20 adds
__VA_OPT__
, which is designed for recursive macros, but there are no such thing in C++!Examples:
fold
reverse token stream
transform token stream ( literaly for each )
calculate count of tokens
boost pfr without code generation
Here magic get expands to (screenshot from clangd builded with this patch)
infinite recursion macro: