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

constructors called twice and have different behaviors/argument values #144

Open
diablodale opened this issue Apr 9, 2020 · 3 comments
Open

Comments

@diablodale
Copy link

Min external constructors have different behaviors and called twice. I would never want my constructor called twice and I want consistent behavior across scenarios.

Setup

  • Min-api 55c65a0
  • Max 7 x64
  • MSVC++ 2019

Code

#pragma warning(push)
    #pragma warning(disable: 4100 4701 4706 4127 4244 4456 4267)
    #include <c74_min.h>
#pragma warning(pop)
#pragma warning(disable: 4100) // hack for c74_min MIN_FUNCTION

using namespace c74::min;

class foobar : public object<foobar> { //public matrix_operator<>
public:
    inlet<>  input	{ this, "input" };
    outlet<> output	{ this, "output" };

    // constructor for specific instance of this max object
    foobar(const atoms& args = {}) {
        cout << "constructor... " << args.size() << " arguments are: ";
        for (auto&& it : from_atoms<std::vector<string>>(args)) {
            cout << it;
        }
        cout << endl;
    }
    message<> setup { this, "setup",
        MIN_FUNCTION {
            cout << "setup()" << endl;
            return {};
        }
    };
    message<> maxclass_setup { this, "maxclass_setup",
        MIN_FUNCTION {
            cout << "maxclass_setup()" << endl;
            return {};
        }
    };
    message<> jitclass_setup { this, "jitclass_setup",
        MIN_FUNCTION {
            cout << "jitclass_setup()" << endl;
            return {};
        }
    };

};
MIN_EXTERNAL(foobar);

Repo 1

  1. Compile
  2. Create patch with single object with single argument -> (foobar myarg)
  3. Run that patch

Result 1

Max console reports the following

constructor... 0 arguments are: 
maxclass_setup()
foobar: constructor... 1 arguments are: myarg

Expected 1

A constructor to only be called once. Since the constructor is in the scope of the "top" max class, then this constructor would have no arguments. Please note, that checking the size() of arguments can not self-distinguish if it is the max class or the instance of that class, because arguments are not required and therefore it is valid to have zero arguments which would make both times the constructor is called appears extremely similar unless some state outside the constructor is used. But that's weird because now we are implementing a language feature (constructor only called once) with a state variable.

Repo 2

  1. Change line 9 class foobar... to be instead the following
    class foobar : public object<foobar>, public matrix_operator<> {
  2. Add a noop calc_cell method to the class
    template<class matrix_type, size_t plane_count>
    cell<matrix_type, plane_count> calc_cell(cell<matrix_type, plane_count> input, const matrix_info& info, matrix_coord& position) {
        cell<matrix_type, plane_count> result = {};
        return result;
    }
    
  3. Compile
  4. Run the same patch above

Result 2

constructor... 0 arguments are:
jitclass_setup()
maxclass_setup()
foobar: constructor... 0 arguments are:
foobar: setup()

Expected 2

In addition to the problem of the constructor running twice, now the second time it runs it no longer receives the "myarg" argument. This is drastically different behavior. The full list of non attribute arguments (non @... arguments) should be available to the constructor.

Notes

The number of times a constructor is called, in what context that constructor is called, and the arguments available to that constructor are all involved in this issue. Without guidance and examples from Cycling74, it is unclear the goal and context of constructors are in Min. Until that is clearer, I don't have any suggestions or fixes.

@sncheca
Copy link

sncheca commented May 18, 2020

Hey diablodale,

There's a thread here (in the min-devkit issues) where they talk about this a bit. But I totally agree that this is odd behaviour, and I wish the constructor would be called just once.

@diablodale
Copy link
Author

@sncheca , thanks for looping in that issue. I'm on another project now, will revisit this in June 2020 and I can test if that's the double I see and also explore that dummy. It seems odd to create a dummy at runtime when all is known at compiletime. We have constexpr and cmake. 🤔

@tap
Copy link
Contributor

tap commented Jun 18, 2020

At the time this code was written, support for constexpr was very uneven (or non-existent) in the compilers across the support platforms.

That situation has likely improved and I agree that revisiting the need for a dummy instance to derive the class template is worth researching if and when time permits.

Cheers

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

No branches or pull requests

4 participants