• Re: How to make the Process ctor work for different R type?

    From red floyd@21:1/5 to wij on Mon Nov 18 20:34:43 2024
    On 11/18/2024 6:38 PM, wij wrote:
    struct Process {
    template<typename R>
    explicit Process(R (*pfunc)(), bool ret_int=false) {
    int pid= fork();
    if(pid==-1) {
    throw "Error";
    }
    if(pid==0) {
    if(ret_int) {
    _exit( pfunc() ); // error: invalid use of void expression
    } else {
    pfunc(); // ret value ignored
    _exit(0);
    }
    }
    };
    }

    The issue is _exit(int) require int type.

    void f();
    Process proc(f); // error: R is void

    So, how to make the Process ctor work for different R type?


    Google for "template specialization".

    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to red floyd on Tue Nov 19 01:04:23 2024
    On 11/18/24 23:34, red floyd wrote:
    ...
    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    Note, however, that _Exit() has been part of ISO C++'s version of the C standard library since 2011. It was originally added in C99, and _exit()
    was added to POSIX in 2001, and is defined as equivalent to _Exit().

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to [email protected] on Tue Nov 19 10:45:34 2024
    On 19.11.2024 10:27, [email protected] wrote:
    On Tue, 19 Nov 2024 01:04:23 -0500
    James Kuyper <[email protected]> boring babbled:
    On 11/18/24 23:34, red floyd wrote:
    ....
    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    Note, however, that _Exit() has been part of ISO C++'s version of the C
    standard library since 2011. It was originally added in C99, and _exit()
    was added to POSIX in 2001, and is defined as equivalent to _Exit().

    exit() flushes buffers before the process exits (in *nix, don't know about windows), _exit() doesn't.


    Even more importantly, exit() executes the destructors of static objects
    and atexit handlers, whereas _exit() does not. So, _exit() is only
    suitable for emergency exit in case of errors (failing to join all child threads, for example).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Tue Nov 19 08:27:25 2024
    On Tue, 19 Nov 2024 01:04:23 -0500
    James Kuyper <[email protected]> boring babbled:
    On 11/18/24 23:34, red floyd wrote:
    ....
    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    Note, however, that _Exit() has been part of ISO C++'s version of the C >standard library since 2011. It was originally added in C99, and _exit()
    was added to POSIX in 2001, and is defined as equivalent to _Exit().

    exit() flushes buffers before the process exits (in *nix, don't know about windows), _exit() doesn't.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Tue Nov 19 09:15:31 2024
    On Tue, 19 Nov 2024 10:45:34 +0200
    Paavo Helde <[email protected]> boring babbled:
    On 19.11.2024 10:27, [email protected] wrote:
    On Tue, 19 Nov 2024 01:04:23 -0500
    James Kuyper <[email protected]> boring babbled:
    On 11/18/24 23:34, red floyd wrote:
    ....
    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    Note, however, that _Exit() has been part of ISO C++'s version of the C
    standard library since 2011. It was originally added in C99, and _exit() >>> was added to POSIX in 2001, and is defined as equivalent to _Exit().

    exit() flushes buffers before the process exits (in *nix, don't know about >> windows), _exit() doesn't.


    Even more importantly, exit() executes the destructors of static objects
    and atexit handlers, whereas _exit() does not. So, _exit() is only

    But doesn't call the destructors of objects on the stack which IMO makes it
    a fairly useless halfway house. Either call all or don't call any.

    suitable for emergency exit in case of errors (failing to join all child >threads, for example).

    Or a system shutdown where you just want to do the most important save functions then immediately die.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paavo Helde@21:1/5 to wij on Tue Nov 19 16:15:29 2024
    On 19.11.2024 15:16, wij wrote:
    On Tue, 2024-11-19 at 07:07 -0500, Sam wrote:
    wij writes:

    struct Process {
        template<typename R>
        explicit Process(R (*pfunc)(), bool ret_int=false) {
          int pid= fork();
          if(pid==-1) {
            throw "Error";
          }
          if(pid==0) {
            if(ret_int) {
              _exit( pfunc() ); // error: invalid use of void expression
            } else {
              pfunc();         // ret value ignored
              _exit(0);
            }
          }
        };
    }

    The issue is _exit(int) require int type.

    void f();
    Process proc(f);   // error: R is void

    So, how to make the Process ctor work for different R type?

    For starters this has to be resolved at compile time, not run time.
    Therefore you can't use ret_int, whose purpose is very obvious, because you >> don't know its value until runtime. Just because it has a default value
    doesn't turn it into a compile-time, constexpr value.

    Fortunately there is a very convenient R here. So the first step is to get >> rid of the useless `ret_int`.

        template<typename R>
        explicit Process(R (*pfunc)()) {

    And now this becomes a boring case of constexpr if:

    #include <type_traits>

    // …


        if constexpr(!std::is_same_v<R,void>)
          _exit( pfunc() );
        } else {
             pfunc();
             _exit(0);
        }

    Thanks. I need C++11 way.

    struct Process {
    template<typename FUNC>
    explicit Process(FUNC func) {
    int pid = fork();
    if (pid == -1) {
    throw "Error";
    }
    if (pid == 0) {
    _exit(func());
    }
    }
    };

    int g() {return 1;}

    void f() {}

    int main() {

    Process proc1(g);

    Process proc2([]() {f(); return 0; });

    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From red floyd@21:1/5 to James Kuyper on Wed Nov 20 07:23:19 2024
    On 11/18/2024 10:04 PM, James Kuyper wrote:
    On 11/18/24 23:34, red floyd wrote:
    ...
    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    Note, however, that _Exit() has been part of ISO C++'s version of the C standard library since 2011. It was originally added in C99, and _exit()
    was added to POSIX in 2001, and is defined as equivalent to _Exit().
    Thank you. I was unaware of that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to red floyd on Wed Nov 20 15:47:28 2024
    red floyd <[email protected]d> writes:
    On 11/18/2024 10:04 PM, James Kuyper wrote:
    On 11/18/24 23:34, red floyd wrote:
    ...
    Also, use exit(), not _exit(). The former is ISO C++, the latter
    is not.

    Note, however, that _Exit() has been part of ISO C++'s version of the C
    standard library since 2011. It was originally added in C99, and _exit()
    was added to POSIX in 2001, and is defined as equivalent to _Exit().
    Thank you. I was unaware of that.

    POSIX also has quick_exit(), which doesn't call the registered atexit
    hooks, but does call registered quick_atexit hooks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Thu Nov 21 16:11:55 2024
    On Thu, 21 Nov 2024 15:27:59 +0100
    Bonita Montero <[email protected]> boring babbled:
    But a proper C++-ish wrapper would look like this:

    template<typename Fn>
    void xfork( Fn &&&fn )
    ^^^

    What?

    if constexpr( same_as<invoke_result_t<Fn>, int> )

    What?

    Have you got something against simply passing std::function ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Fri Nov 22 09:54:43 2024
    On Thu, 21 Nov 2024 17:59:21 +0100
    Bonita Montero <[email protected]> boring babbled:
    Am 21.11.2024 um 17:11 schrieb [email protected]:
    On Thu, 21 Nov 2024 15:27:59 +0100
    Bonita Montero <[email protected]> boring babbled:
    But a proper C++-ish wrapper would look like this:

    template<typename Fn>
    void xfork( Fn &&&fn )
    ^^^

    What?

    Just a typo.

    if constexpr( same_as<invoke_result_t<Fn>, int> )

    What?
    Have you got something against simply passing std::function ?

    A std::function isn't necessary here since I don't need any type erasure
    with that.

    Gibberish.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)