Skip to content

Support explicit parameter functions#107121

Closed
lawnjelly wants to merge 1 commit intogodotengine:masterfrom
lawnjelly:explicit_param_funcs4
Closed

Support explicit parameter functions#107121
lawnjelly wants to merge 1 commit intogodotengine:masterfrom
lawnjelly:explicit_param_funcs4

Conversation

@lawnjelly
Copy link
Copy Markdown
Member

@lawnjelly lawnjelly commented Jun 4, 2025

Prevent implicit parameter conversions for specific functions using a macro.

Implicit conversion can sometimes be an indicator of bugs, we use them quite a bit with the basic types, but we identified a desire in the core meeting today to be able to selectively apply explicit protection for parameters in certain functions.

Just adding a draft here to foster more discussion, I'm sure template / macro fu could be applied to make it "more better". 😁

float f = round(0.3f); // works
float f = round(3); // compile error

Notes

  • I'm sure there are much better ways of doing this but it's kind of fun to get the ball rolling.
  • Another alternative is to enable the compiler warning for specific sections of code.
  • Another way is adding function versions for disallowed types, and deleting these versions.
  • I also tried creating an explicit struct for passing but had no joy (e.g. explicit_param<float>) as I couldn't get it to accept float input.

Prevent implicit parameter conversions for specific functions using a macro.
@Ivorforce
Copy link
Copy Markdown
Member

Ivorforce commented Jun 5, 2025

I tinkered a bit, looks like with C++20 it will be possible in a pretty minimalistic way:

template <typename T, typename U>
concept exact_type_t = std::is_same_v<T, U>;

int add(exact_type_t<int> auto p_lhs, exact_type_t<int> auto p_rhs) {
    return p_lhs + p_rhs;
}

int main() {
    std::cout << add(2, 3); // Works
    std::cout << add(2l, 3); // Static error
    return 0;
}

It's especially nice how no template is needed. The only thing I dislike is needing the 'auto' but I suppose that's just how it is.

Edit: Actually, this exact concept is a core C++20 feature apparently, so we don't even need our own concept:

int add(std::same_as<int> auto p_lhs, std::same_as<int> auto p_rhs) {
    return p_lhs + p_rhs;
}

int main() {
    std::cout << add(2, 3); // Works
    std::cout << add(2l, 3); // Static error
    return 0;
}

@lawnjelly
Copy link
Copy Markdown
Member Author

lawnjelly commented Jun 9, 2025

Sorry, was away, that sounds great that there is a more idiomatic way of doing this in c++20!
That will be ideal for changing when we do convert to c++20. To be honest I was surprised there wasn't a standard way of doing this already in the language, I'm not sure exactly why they haven't got the explicit keyword to do this already.

The whole std::same_as<int> auto p_lhs is a little bit verbose and typical of the "overly c++" std way of doing things so it might be worth considering a simper macro / template when we come to implement.

It would have been nice to have something that could be used in 3.x too but I guess the codebase is pretty mature and it isn't so much of a problem (even error checking could be done by temporarily adding the compiler warning I guess).

I'll close this then, but we can reference it when we discuss c++20 changes in a core meeting for 4.6. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants