0

I have some code that realise my Tuple class. Idea: Receive pointer to arguments. Step over them. If argument not real: tipeid(exp).name() throw exception. But in 50% I can catch it and in 50% I can't catch it.

#include <iostream>

class Object {
public:
    Object() {};
    ~Object() {};
    virtual void func() {}
};

class A : public Object {
public:
    A(int a) { this->value = a; };
    void func() {};
private:
    int value;
};

class Tuple : public Object {
public:
    Tuple(Object *obj, ...) {
        Object **pobj = &obj;
        int objs_size = 0;
        // solve the objs_size:
        while (true) {
            try {
                typeid(**pobj).name(); // ! This MUST throw bad_typeid exception, then pobj out of input.
                objs_size++;
                pobj++;
            } catch (...) {
                break;
            }
        }
        pobj = &obj;
        // Useful code
        // ...
    };
    ~Tuple() {
        delete[] items;
    };
private:
    void resize(int i) {
        this->size = i;
        delete[] items;
        items = new Object*[i];
    };
    Object **items = new Object*[0];
    int size = 0;
};

Tuple foo() {
    // Creating some data;
    A* a = new A(1);
    A* b = new A(2);
    A* c = new A(3);
    // Creating Tuple
    return Tuple{a, b, c};
}

Tuple* pfoo() {
    // Creating some data;
    A* a = new A(1);
    A* b = new A(2);
    A* c = new A(3);
    // Creating Tuple
    return new Tuple{a, b, c};
}

int main() {
    Tuple t = foo(); // this works

    Tuple* pt = pfoo(); // this works

    // Creating some data;
    A* a = new A(1);
    A* b = new A(2);
    A* c = new A(3);
    // Creating Tuple
    Tuple* pt2 = new Tuple{a, b, c}; /*
    Run:

    Process finished with exit code -1073741819 (0xC0000005)

    Debugger run:

    Signal: SIGSEGV (Segmentation fault)
    Signal: SIGSEGV (Segmentation fault)

    Process finished with exit code 1
    
    Debugger shows that it from "typeid(**pobj).name();". Why can't I catch this?
 */

    Tuple t2 = Tuple{a, b, c}; // It too crush my example as previous initing Tuple with new.
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

But this code crushs how it say in comments in code. I can maybe change constuctor to:

Tuple(int objs_size, Object* obj, ...) {...};

But its not in my interests. (I'm lazy, and I don't want to calculate the number of arguments.) How it solve?

dail45
  • 31
  • 4
  • 3
    You must use `va_arg` to process variadic fubctions. The `pobj++` trick is not portable. In this case, a variadic template is a better choice – Raymond Chen Jul 27 '22 at 04:35
  • Apparently, you need to do some extra work before you can catch a segmentation fault signal https://stackoverflow.com/questions/2350489/how-to-catch-segmentation-fault-in-linux `Unfortunately, it is not possible to catch a SIGSEGV from within a C++ program without introducing undefined behavior` (quoted from https://stackoverflow.com/a/53436496/4225384 ) – qrsngky Jul 27 '22 at 04:37
  • `...` in your parameter list is not typed, let alone does it inherit the `Object*` type of the preceding parameter. Use a template parameter packs instead, see https://en.cppreference.com/w/cpp/language/parameter_pack. – Ulrich Eckhardt Jul 27 '22 at 05:14

0 Answers0