Skip to content

Add scip::ObjExprhdlr class to objscip #149

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

Merged
merged 6 commits into from
Jun 5, 2025
Merged

Conversation

kkofler
Copy link
Contributor

@kkofler kkofler commented May 31, 2025

The intent is to be able to use SWIG director classes to implement expression handlers through bindings, in particular, to add support for expression handlers to JSCIP. That needs the C++ class to build upon.

src/objscip/objexprhdlr.h, src/objscip/objexprhdlr.cpp: New files. C++ wrapper for expression handlers. The files contain the scip::ObjExprhdlr class and the functions SCIPincludeObjExprhdlr, SCIPfindObjExprhdlr, and SCIPgetObjExprhdlr.

src/CMakeLists.txt (objscipsources): Add objscip/objexprhdlr.cpp.
(objscipheaders): Add objscip/objexprhdlr.h.

The intent is to be able to use SWIG director classes to implement
expression handlers through bindings, in particular, to add support for
expression handlers to JSCIP. That needs the C++ class to build upon.

src/objscip/objexprhdlr.h, src/objscip/objexprhdlr.cpp: New files. C++
wrapper for expression handlers. The files contain the scip::ObjExprhdlr
class and the functions SCIPincludeObjExprhdlr, SCIPfindObjExprhdlr, and
SCIPgetObjExprhdlr.

src/CMakeLists.txt (objscipsources): Add objscip/objexprhdlr.cpp.
(objscipheaders): Add objscip/objexprhdlr.h.
@svigerske svigerske self-assigned this May 31, 2025
svigerske added 2 commits June 4, 2025 20:16
- derive from ObjCloneable: copy doesn't get invalid if exprhdlr cannot be
  cloned
- no need for cassert in objexprhdlr.h
- linebreaks closer to SCIP style
@svigerske
Copy link
Member

@kkofler Are you ok with the current changes to your changes?

@kkofler
Copy link
Contributor Author

kkofler commented Jun 4, 2025

Yes, looks good now. Thank you for your improvements to my contribution.

@scip-ci scip-ci merged commit 51bbcfc into scipopt:master Jun 5, 2025
1 check passed
@svigerske
Copy link
Member

Thank you for the contribution!

@kkofler
Copy link
Contributor Author

kkofler commented Jun 19, 2025

Unfortunately, now that I am finally far enough with my Java bindings to be able to really test this, I have found an annoying issue, but I am not sure about the proper fix: The problem is: The Java ExpressionHandler class wants to call SCIPincludeObjExprhdlr in the constructor (in any constructor, even the copy constructor) so that it can remember the corresponding C SCIP_EXPRHDLR * pointer. As a result, the implementation of the clone operation (called by the ObjExprhdlr implementation of copyhdlr) is also going to indirectly call SCIPincludeObjExprhdlr from the Java code.

However, the C++ code also tries to directly call SCIPincludeObjExprhdlr in copyhdlr:

      /* call include method of expression handler object */
      SCIP_CALL( SCIPincludeObjExprhdlr(scip, newobjexprhdlr, TRUE) );

That was not my idea: At least ObjConshdlr does the exact same thing, I just adapted that code here.

As a result, the expression handler is going to be included twice, with both (duplicate) SCIP_EXPRHDLRs pointing to the same ObjExprhdlr. This eventually results in a double-free, and then all hell may break loose. (In my tests, I ended up running into a mysterious assertion failure that turned out to be caused by memory corruption: the second free was use-after-free-ing a SCIP * pointer that was already overwritten, and complaining that it did not match the passed SCIP *. But the behavior is undefined, so it can fail in many other ways.)

I tried simply commenting out that SCIP_CALL( SCIPincludeObjExprhdlr(scip, newobjexprhdlr, TRUE) ); line in objexprhdlr.cpp (pushing the reponsibility of calling that method down to the clone implementation) and that fixed it for me. However, then we should also change that behavior in objconshdlr.cpp (and any other objscip classes that do the same, if any) for consistency.

Fixing this in the JSCIPOpt Java code is not easy, also because, as I already mentioned, SCIPincludeObjExprhdlr is what gives me the SCIP_EXPRHDLR * pointer.

So I am not sure what the proper fix is here.

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

Successfully merging this pull request may close these issues.

3 participants