• Re: Q: how to make an object that throws

    From Zhengyi Fu@21:1/5 to Ross Finlayson on Tue Apr 23 11:08:08 2024
    Ross Finlayson <ross.a.finlayson@gmail.com> writes:

    Hello I hope I might consult your expertise, I'm wondering about
    a use-case where for a given library object, to provide an instance
    of same type, that on any access, throws an exception.

    The idea is that there's an idea in a different language where
    the runtime throws a null_pointer_dereference exception
    when dereferencing a null pointer, yet in C++ it's signal segfault.

    So, what I wonder about is how to make an object in C++,
    of a given standard library type, and any arbitrary type,
    that on any access, throws.

    I suppose I might static_cast an object yet I wonder how
    to make it so then that any access to it throws.

    As you might imagine it's a use-case for exceptions
    as part of flow-of-control, that in the other language
    just is null yet in C++ would be for "an object of all types",
    that throws on any access.


    I believe there is no portable way to implement this.

    However, if you are running GCC on supported platforms, you can try
    the `-fnon-call-exceptions` option.

    --8<---------------cut here---------------start------------->8---
    // main.cpp
    #include <sys/types.h>
    #include <signal.h>
    #include <iostream>
    #include <exception>

    extern "C" void handle_signal(int signum) {
    throw std::runtime_error("Invalid access");
    }

    int main()
    {
    struct sigaction act;
    act.sa_handler = &handle_signal;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_NODEFER;
    sigaction(SIGSEGV, &act, nullptr);

    int *object = NULL;

    try {
    // write
    *object = 100;
    } catch (std::exception& exc) {
    std::cerr << "Caught exception: " << exc.what() << '\n';
    }

    try {
    // read
    int value = *object;
    std::cout << "value = " << value << '\n';
    } catch (std::exception& exc) {
    std::cerr << "Caught exception: " << exc.what() << '\n';
    }
    }
    --8<---------------cut here---------------end--------------->8---

    Compile the source file with

    g++ -fnon-call-exceptions -o test main.cpp

    Run ./test, it outputs

    Caught exception: Invalid access
    Caught exception: Invalid access

    --
    Zhengyi Fu

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sam@21:1/5 to Ross Finlayson on Mon Apr 22 22:32:49 2024
    Ross Finlayson writes:

    Hello I hope I might consult your expertise, I'm wondering about
    a use-case where for a given library object, to provide an instance
    of same type, that on any access, throws an exception.

    What does "any access" mean? Please be specific.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sam@21:1/5 to Ross Finlayson on Tue Apr 23 07:26:59 2024
    Ross Finlayson writes:

    On 04/22/2024 07:32 PM, Sam wrote:
    Ross Finlayson writes:

    Hello I hope I might consult your expertise, I'm wondering about
    a use-case where for a given library object, to provide an instance
    of same type, that on any access, throws an exception.

    What does "any access" mean? Please be specific.


    As if it were null, whatever would raise a segfault,
    is the idea of "any access", then I wish I better

    Again, you need to explain what "whatever" means.

    Are you looking for a class with deleted copy/move constructors or
    assignment operators?

    Are you looking for a class with an overloaded * or -> operator that throws
    an exception?

    /What/ are you looking for?

    explain the differences among pointers, references, and
    class returns from functions, looking at C++ 11,
    and trying to understand some of the newer syntactic
    sugar with regards to declarations.

    Perhaps it would be more productive to invest a little bit more time
    studying C++11, and learning the different parts of C++, what they are, and
    how they work, before attempting to ask a meaningful question.

    The term "any access" is utterly meaningless and context-free, in C++ terms. Nobody really understands what exactly you're asking.



    std::vector<int> values() {
    return static_cast<std::vector<int>> nullptr; // no
    }

    No self-respecting C++ compiler will compile this. This is syntactically invalid.

    The idea is that some code can compute partial results,
    or to the effect of launching asynchronous requests

    void rr1(const std::string& s) {

    std::list<std::string> l1 = rr2(s);

    int i1 = rr3(s);
    int i2 = rr4(s);

    int siz = l1.size(); // throw

    int i3 = rr5(i1, i2, l1.size());

    }

    What is "rr2"? What is "rr3"? What is "rr4"? What is "rr5"?

    so the idea is the re-routine runs through statements
    as long as the inputs are satisfied, then these

    What "inputs"? What does "satisfied" mean?

    rr1, 2, 3, 4, 5 throw if their arguments are the
    null_throwing type, and any library code access

    What does "null_throwing" mean?

    C++ is very complicated. When discussing C++ it is very important to be explicit and use consistent terms that are well-defined in C++.

    [deletia]

    It's an idea for writing co-routines in the language

    You will do yourself a huge, huge favor, by forgetting everything about co- routines.

    co-routines are a solution in search of a problem.

    The only reason co-routines exist in C++ is because real execution threads absolutely suck raw eggs in Microsoft Windows, and Microsoft hijacked the standardization process to infect C++ with this co-routines bullshit just so that MS-Windows would finally have a multi-threading implementation model
    that does not suck.

    This way then the re-routine sort of automatically
    primes its asynchronous results in whatever results
    getting to the invoked re-routines, "satisfied" or
    "satisfying" inputs, so that they're initiated
    with completion handlers to populate the monad
    and push the next re-run or the re-routine to
    the task queue, which flows in the otherwise
    flow-of-control in the language exactly the same
    each time until it itself actually completes
    and calls back to the originating (initiating)
    callback (completion handler).

    Go ask Microsoft. They invented all this bullshit. They can deal with it,
    by themselves.

    (It's been a while, I need to learn C++ 11

    co-routines are not C++11.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sam@21:1/5 to Ross Finlayson on Tue Apr 23 22:08:20 2024
    Ross Finlayson writes:

    The idea is that this sort of approach to cooperative multithreading
    needs thread_local storage specifier, and, basically aspects to
    instrument the routine with its semantics of memoizing its results
    in the partial monad of the sub-routines' results in the re-launches,
    that the re-routine invokes all its asynchronous dependencies going
    along, those returning their memoized results if available else
    these null-throwing placeholders while launching themselves,
    that it results non-blocking routines in re-routines,
    with nothing at all about the semantics of asynchrony or callback,
    because in the aspect its implicit, in the language,
    in the defined behavior of the language and runtime.

    So, right, it's not runtime or library coroutines or in the language
    anything at all with the semantics of asynchrony, the idea is
    re-routines that can be sort of implemented in regards to there
    being virtual functions for these aspects, and thread_local storage,
    and threads, for a pattern (anti-pattern) of non-blocking re-routines.

    So, I suppose that would require C++ 11 for threads and thread_local,
    while, otherwise it would be a usual simple sort of portability layer.

    That's a little bit above my pay grade. I am focused on the narrow question
    of "how to make an object that throws", upon "access". I'm very confident
    that there is a C++ answer to this question, as soon as "access" gets
    defined concisely, using C++ terms and terminology.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Zhengyi Fu on Wed Apr 24 19:26:26 2024
    Zhengyi Fu <i@fuzy.me> wrote or quoted:
    int *object = NULL;

    This seems to be what's helping the OP, but when you consider
    that the subject line is "how to make an object that throws",
    you'd actually have to say that the thrower here is not an
    object, but rather the /absence of an object/.

    This of course has to do with how objects are specified.

    In C++, an expression can stand directly for an object, so
    an assignment copies that object. In other languages, objects
    are always implicitly specified by references/pointers, and
    an assignment copies that reference/pointer. This can make it
    appear sometimes as if a reference/pointer is an object.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Stefan Ram on Thu Apr 25 14:08:58 2024
    ram@zedat.fu-berlin.de (Stefan Ram) writes:

    Zhengyi Fu <i@fuzy.me> wrote or quoted:

    int *object = NULL;

    This seems to be what's helping the OP, but when you consider
    that the subject line is "how to make an object that throws",
    you'd actually have to say that the thrower here is not an
    object, but rather the /absence of an object/.

    This of course has to do with how objects are specified.

    In C++, an expression can stand directly for an object, so
    an assignment copies that object. In other languages,

    In some other languages. Certainly not all other languages.

    objects
    are always implicitly specified by references/pointers, and
    an assignment copies that reference/pointer.

    Some languages that use pointer semantics rather than using
    "objects" directly don't have a way to do assignment, so the
    question of what is copied is moot.

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