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

[SUGGESTION] How to cast int to std::size_t #104

Closed
filipsajdak opened this issue Oct 31, 2022 · 5 comments
Closed

[SUGGESTION] How to cast int to std::size_t #104

filipsajdak opened this issue Oct 31, 2022 · 5 comments

Comments

@filipsajdak
Copy link
Contributor

filipsajdak commented Oct 31, 2022

Thanks to #93 I was able to implement the main function that takes arguments.

main: (argc : int, argv : **char) -> int = {
    // ...
}

but then argv is a pointer and the pointer arithmetic checks will kick in (another PR is needed to achieve that - already on the list). From the messages provided by the safety check, I know that we recommend using std::span.

When I try to construct std::span I can use pointer and std::size_t argument to construct the span but argc is an int. How to do narrowing conversion in cpp2 way? using argc as std::size_t is not working as it matches

static std::nullptr_t nonesuch = nullptr;

template< typename C >
auto as(...) -> auto {
    return nonesuch;
}

and fails miserably as a runtime crash :(.

What worked for me right now is

    args : std::span<Arg> = (argv, static_cast<std::size_t>(argc));
    // Arg is `using Arg = char*;` as there is an issue with std::span<char*> 
    // or std::span<*char> (star disappears) 

but I believe we can do better.

By the way, returning nonesuch without a warning when something doesn't match defined cases is a really bad idea - I was looking for an error why the below code ends with a crash:

    args : std::span<Arg> = (argv, argc as std::size_t);
    c : std::ifstream = args.back(); // <= here it crashes

Probably it is better to do static_assert for cases that don't match or something that will give a hint of what is not working.

@hsutter
Copy link
Owner

hsutter commented Jan 6, 2023

This is now resolved, and the example below works:

main: (argc: int, argv: **char) -> int = {
    args : std::span<*char> = (argv, argc as std::size_t);
    c : std::ifstream = args.back(); // <= now ok
}

Thanks!

@hsutter hsutter closed this as completed Jan 6, 2023
@filipsajdak
Copy link
Contributor Author

Excellent solution! Thanks for cooperating on that!

@gregmarr
Copy link
Contributor

gregmarr commented Jan 6, 2023

I thought that there had been a discussion about how to make the main parameters safe by default, but I wasn't able to find it. Is there a plan already spelled out somewhere?

@JohelEGP
Copy link
Contributor

JohelEGP commented Jan 6, 2023

There was #63.

@gregmarr
Copy link
Contributor

gregmarr commented Jan 6, 2023

Thanks Johel, I think that's what I was thinking of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants