[SCIP] ODR violation when using multiple constraint handlers in C++

Leona Gottwald gottwald at zib.de
Mon Oct 26 10:40:07 CET 2020


To add to this,

the structs need to be POD (Plain Old Data) I believe, see 
https://en.cppreference.com/w/cpp/named_req/PODType

Default initializers, constructors, and destructors are therefore not
allowed. Problems may come up as destructors/constructors/initializers
implicitly cause a member function to be created which then collides at
the linking stage with member functions of the other structs.

Leona

Am Freitag, den 23.10.2020, 10:04 +0200 schrieb Marc Pfetsch:
> 
> Dear Georg,
> 
> the C++-11 standard says:
> 
> "Only one definition of any variable, function, class type,
> enumeration
> type, concept (since C++20) or template is allowed in any one
> translation unit."
> 
> Thus, I think you can have different definitions of structs in
> different
> C++ files (= translation units?) and I would expect that the general
> procedure of SCIP should work. (I have assumed that structs are
> treated
> similar to classes.)
> 
> Can you check whether you have a default initialization of the
> members
> of your structs? This does not seem to work, as we discussed
> yesterday
> on this mailing list. If this is the case, just remove them and
> initialize when you create the structs.
> 
> (Of course you should also not have static members of your structs.)
> 
> Moreover, you can check whether this is just a warning and the code
> will
> work nevertheless (-Wno-odr would probably disable the warning).
> 
> You might also want to use the SCIP C++ interface in which you can
> use
> classes and put your data into these classes. Of course, the same
> problem could arise in SCIP code, but I have not seen this
> previously.
> In fact, I have had many branching rules using the C++ interface and
> there was no problem - however, this was before C++-11.
> 
> Best
> 
> Marc
> 
> 
> On 23/10/2020 01:32, Georg Brandstätter wrote:
> > Dear SCIP developers,
> > 
> > I'm using SCIP as a branch-and-price framework (with Cplex as LP
> > solver)
> > from my C++ application. I've now stumbled across the following
> > problem:
> > 
> > I've implemented two custom branching rules (Ryan-Foster + another)
> > to
> > handle branching without having to perform binary branching on my
> > priced
> > variables. These two branching rules are each implemented with a
> > custom
> > constraint handler that adds branching constraints to a B&B node's
> > children. The two types of constraints are quite different and
> > therefore
> > each need different data associated SCIP_CONSDATA.
> > 
> > As I understand, I would therefore need to define two different
> > "struct
> > Scip_ConsData" - one for each type of branching constraint.
> > However,
> > this is a violation of the One Definition Rule in C++, as you
> > cannot
> > have two identically-named structs in your program. According to
> > the
> > standard (as I understand it), this leads to undefined behavior.
> > The
> > linker also emits the following warning:
> > 
> >     warning: type ‘struct SCIP_ConsData’ violates the C++ One
> > Definition
> > Rule [-Wodr]
> >     struct SCIP_ConsData
> > 
> > From what I understand, this is not a problem in C, where
> > identically-named structs are allowed in different .c files. In
> > C++,
> > however, this seems to be forbidden.
> > 
> > Can you give me some hint as to how to best proceed from here? I
> > have
> > only found SCIP examples in C++ that use a single custom constraint
> > handler (e.g., your TSP example), where that problem obviously
> > doesn't
> > occur as one such global definition of "struct SCIP_ConsData" is
> > allowed
> > even in C++.
> > 
> > So far, I've considered the following workarounds:
> > 
> > * Use the same SCIP_ConsData struct for both types of branching
> > constraint that contains the required data for both constraint
> > types
> > (those that are not needed in the current constraint type are
> > simply
> > ignored/filled with some dummy data)
> > 
> > * Use the same trivial SCIP_ConsData struct for both constraint
> > types
> > that contains only some constraint id. The actually relevant
> > constraint
> > data is then saved in some std::vector within the respective
> > constraint
> > handler classes and retrieved with that constraint id.
> > 
> > However, both these variants seem rather sketchy. Is there a better
> > way
> > of storing constraint data in C++ that I'm missing, or is that
> > simply
> > not possible within SCIP?
> > 
> > 
> > Best,
> > Georg
> > 
> > _______________________________________________
> > Scip mailing list
> > Scip at zib.de
> > https://listserv.zib.de/mailman/listinfo/scip
> _______________________________________________
> Scip mailing list
> Scip at zib.de
> https://listserv.zib.de/mailman/listinfo/scip



More information about the Scip mailing list