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

Marc Pfetsch pfetsch at mathematik.tu-darmstadt.de
Fri Oct 23 10:04:01 CEST 2020



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


More information about the Scip mailing list