-
Notifications
You must be signed in to change notification settings - Fork 266
Description
CPP2_UFCS macro is based on variadic macros. That means that every comma ,
in the macro separates two arguments for the macro (unless surrounded by parentheses ()
.
That makes below the cpp2 code (mixed mode):
#include <string>
template <auto from, auto to>
auto substr(const std::string& input) -> std::string {
return input.substr(from, to-from);
}
main: () -> int = {
test_string: std::string = "Unfortunatelly macros have limitations";
cmd.substr<3,6>();
}
compiles to (skipping boilerplate):
[[nodiscard]] auto main() -> int{
std::string test_string { "Unfortunatelly macros have limitations" };
CPP2_UFCS_0(substr<3,6>, test_string);
}
And a call to CPP2_UFCS_0
will be perceived by the compiler as CPP2_UFCS_0((substr<3),(6>), (test_string));
(parentheses added to emphasize the problem. That will not compile and will end up with an error:
clang++ -std=c++20 -Iinclude ../tests/ufcs-method-limitations.cpp
tests/ufcs-method-limitations.cpp2:10:30: error: too many arguments provided to function-like macro invocation
CPP2_UFCS_0(substr<3,6>, test_string);
^
include/cpp2util.h:487:9: note: macro 'CPP2_UFCS_0' defined here
#define CPP2_UFCS_0(FUNCNAME,PARAM1) \
^
tests/ufcs-method-limitations.cpp2:10:5: error: use of undeclared identifier 'CPP2_UFCS_0'
CPP2_UFCS_0(substr<3,6>, test_string);
^
2 errors generated.
A similar error will happen for CPP2_UFCS
version - that reminds me why we hate macros so much.
Normally, in such cases, we would add parentheses to give hints to the preprocessor where are the arguments. In this case when we do it we will look like:
CPP2_UFCS_0((substr<3,6>), test_string);
But it will also fail to compile with the error: expected unqualified-id
:
clang++ -std=c++20 -Iinclude ../tests/ufcs-method-limitations.cpp
tests/ufcs-method-limitations.cpp2:10:17: error: expected unqualified-id
CPP2_UFCS_0((substr<3,6>), test_string);
^
tests/ufcs-method-limitations.cpp2:10:17: error: expected unqualified-id
error: constexpr if condition is not a constant expression
tests/ufcs-method-limitations.cpp2:10:5: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<std::string &>' requested here
CPP2_UFCS_0((substr<3,6>), test_string);
^
include/cpp2util.h:494:2: note: expanded from macro 'CPP2_UFCS_0'
}(PARAM1)
^
3 errors generated.
Unless there is a trick to make that macro work again we will need to come up with some other idea to solve it.
I found that bug while trying to update the function call chaining PR (#18). Probably working UFCS will not be possible without semantic analysis on cppfront side.
The same will be needed to allow Unified "." member/scope selection (e.g., std.swap(x,y))
- it is impossible to distinguish if std
is a namespace by using require
expressions or decltype
hacks (already tried that).