Repository navigation
Conversation
- SCIPstatDebugMessagePrint() passed its va_list to printf(); use vprintf() - cons_nonlinear.c: use SCIPsnprintf() instead of sprintf() - tpi_openmp.c: report an unknown job id with SCIPerrorMessage() instead of printing "err1" - dijkstraGraphIsValid() returns FALSE for an invalid graph instead of calling abort(); it is only called inside assert(), like dijkstraHeapIsValid()
… the embedding program Code that cannot use a message handler now writes to stdout and stderr and terminates through SCIPioPrintStdout(), SCIPioPrintStderr(), SCIPioVPrintStdout(), SCIPioVPrintStderr(), SCIPioExit() and SCIPioAbort(), and message.c uses SCIPioGetStdout() and SCIPioGetStderr() where it used stdout and stderr. By default these are macros for the C library, so default builds compile to the same code as before. With CUSTOMIO (SCIP_CUSTOM_IO in config.h) they are functions that the program linking SCIP defines, together with SCIPcreateMessagehdlrDefault(). io_default.c (their C library implementations), message_default.c and scipshell.c are then left out of the library and built into the scip executable. CUSTOMIO requires SHARED=off. Where a SCIP message routine is reachable it is used instead: dialog_default.c uses SCIPdialogMessage(), and the default scip_print() of ObjConshdlr uses SCIPinfoMessage(). The tclique sources include pub_misc.h themselves, not through tclique_def.h, because tclique.h includes tclique_def.h inside extern "C". scripts/check_scip_defs.sh excludes SCIP_CUSTOM_IO: the Makefile build does not provide the functions. Vendored nauty and dejavu and the SoPlex code instantiated in lpi_spx.cpp are unchanged.
bnaras
added a commit
to bnaras/scip
that referenced
this pull request
Oct 20, 2026
Record the functionality PR scipopt/scip#236
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the functionality PR discussed in #194: a CMake option
CUSTOMIOwith which libscip itself no longer referencesstdout,stderr,printf(),exit()orabort(). The program that links SCIP supplies a few functions instead. Without the option, the build compiles to the same code as before, apart from the fixes listed below.Mechanism
pub_misc.h, new group "Standard Streams and Termination":SCIPioPrintStdout(),SCIPioPrintStderr(),SCIPioVPrintStdout(),SCIPioVPrintStderr(),SCIPioExit(),SCIPioAbort(),SCIPioGetStdout(),SCIPioGetStderr().printf,fprintf(stderr, ...),vprintf,vfprintf(stderr, ...),exit,abort,stdout,stderr.SCIP_CUSTOM_IO(config.h, set by-DCUSTOMIO=on): declarations. The two variadic ones are defined inmisc.c; the program defines the other six.CUSTOMIO,io_default.c(the C library versions of the six),message_default.c, andscipshell.care left out of libscip and built into thescipexecutable, which then links and behaves as before. The program that links SCIP defines the six functions andSCIPcreateMessagehdlrDefault().scip_general.cis unchanged.message.ccompares and passesSCIPioGetStdout()/SCIPioGetStderr()where it usedstdout/stderr, so theFILE*handed to message handlers keeps its meaning. A program may return stand-in values that its handler recognizes; SCIP only compares them. The default error printer writes throughSCIPioPrintStderr()underCUSTOMIO.CUSTOMIOrequiresSHARED=off. A shared libscip with undefined symbols does not link on macOS or Windows, so CMake stops with a message. If you want shared builds too, this could add-undefined dynamic_lookupon macOS instead.CUSTOMIOtheir ctest build steps fail to link.makeitself is not affected, because they areEXCLUDE_FROM_ALL. Only thecheck/tests of thescipexecutable apply. If you would rather have CMake leave them out underCUSTOMIO, I can add that.scripts/check_scip_defs.shbuilds with every#ifdefname ofsrc/scipdefined, which would includeSCIP_CUSTOM_IO. The Makefile does not buildio_default.c, so itsscipbinary would lack the six functions;SCIP_CUSTOM_IOis added to the script'sEXCLUDES.SCIP_VERSION_API; the new functions are declared only withCUSTOMIO, and your history shows the bump in its own commit. Happy to add it if you want it here.Sites
Existing SCIP routines where one is reachable, the new functions otherwise:
message.cstdout/stderr→SCIPioGetStdout()/SCIPioGetStderr(); default error printerdisp.cfflush(stdout)only withoutCUSTOMIO(the message handler flushes)expr.c,nlp.c,nlpioracle.c,reader_gms.cfile = stdoutdefaults →SCIPioGetStdout()reader_opb.cSCIPprintCons(..., stderr)→SCIPioGetStderr()interrupt.c,dialog.c,matrix.c,stat.c,rational.cppprintf/vprintf/putchar/std::cout/exit→SCIPio*(SCIPrationalPrint()keepsstd::coutwithoutCUSTOMIO)blockmemshell/memory.cprintInfoandBMSprintBufferMemory()→SCIPioPrintStdout(), only in theWITH_SCIPDEFbranchtclique/tclique_def.h,xml/xmldef.h,xml/xmlparse.cprintf/fprintf(stderr, ...)/abort→SCIPio*;pub_misc.his included by the threetclique.cfiles, becausetclique.hincludestclique_def.hinsideextern "C"dialog_default.cprintf→SCIPdialogMessage()objscip/objconshdlr.hscip_print()→SCIPinfoMessage(scip, file, ...)instead offprintf(stdout, ...)dialog_default.candobjconshdlr.hnow print through the message handler, so these lines respect quiet mode. Everything else prints as before.Fixes on their own merits:
SCIPstatDebugMessagePrint()passed itsva_listtoprintf(); it now usesvprintf(also onv101-bugfix).cons_nonlinear.c:sprintf→SCIPsnprintf.tpi_openmp.c:printf("err1")→SCIPerrorMessage()with the job id.dijkstraGraphIsValid()returnsFALSEinstead of callingabort(). It is only called insideassert(), likedijkstraHeapIsValid(), which already returnsFALSE.Not changed
With
CUSTOMIO, these objects of libscip still reference flagged symbols:nauty/*.c(exit,stderr,stdout) andsymmetry/compute_symmetry_sassy_nauty.cpp(std::cout, from the dejavu headers): vendored, left untouched as you preferred. Is a small follow-up for nauty'sexitcalls of interest?lpi/lpi_spx.cpp(abort,std::cout,std::cerr): instantiated from SoPlex headers. I will open an issue at SoPlex.Verification
R's own compiled-code check (
tools:::so_symbol_names_tableagainstnm -Pgundefined symbols), on:TPI=none;TPI=omp,_FORTIFY_SOURCE=3;TPI=omp,LPS=none.Results:
CUSTOMIO: flagged symbols per object are the same as for plainmaster723f18f2de, except the three removed by the fixes (dijkstra.cabort,cons_nonlinear.csprintf,dialog_default.cprintf). On macOS, 429 of the 433 libscip objects have the same disassembly as with plainmaster(addresses and line numbers masked); the other four aredialog_default.c,stat.c,cons_nonlinear.canddijkstra.c.CUSTOMIO: libscip's flagged objects are only those under "Not changed". The CMake builds on the three platforms above, with and withoutCUSTOMIO, compile without warnings.scipexecutable, with vs withoutCUSTOMIO: same output onbell5.mps,p0033.osil,MANN_a9.clq.lp, a missing file, a malformed OSiL file (stderr) and commands from stdin, apart from timings.SCIPcreateMessagehdlrDefault()) links against theCUSTOMIOlibscip with nothing unresolved and solves a MIP, on macOS and Linux.BUILD_TESTING=on, the R package's configuration): withoutCUSTOMIO, 1539 of 1542 pass; the other three (Issue-seed_1-4304.nl,MINLP-readertest-nl-bip_cross_min.10.10.10.1.pip,unittest-cons-superindicator-slack) fail the same way on plainmasterwith this configuration, which hasAMPL=offandZLIB=off. WithCUSTOMIO, thecheck/tests pass apart from the same two.nltests; the 168 build steps of unit tests, examples and applications fail to link on exactly the seven functions (plusSCIPprocessShellArguments()/SCIPrunShell()where they usescipshell.c), and the 272 tests that depend on them do not run.scripts/check_scip_defs.sh's build matrix (LPS=none; gcc, g++, clang, clang++; dbg and opt; gcc 13 and clang 23 on Linux): same make exit status, errors, warnings and number of compiled objects as plainmaster. Plainmasterdoes not compile as C++ (with CMakeCXXONLY=onon macOS, 10 errors in six files, for examplecons_pseudoboolean.c:239), so these runs usedmake -kand compared the results instead of stopping at the first error. CMakeCXXONLY=onbuilds on macOS, with and withoutCUSTOMIO, have the same errors as plainmasterand the same warnings except thesprintfdeprecation warning that thecons_nonlinear.cfix removes;io_default.ccompiles as C++ without warnings.scripts/check_scip_style.prlreports nothing new in the changed files.CUSTOMIO) compile without warnings and solvep0033.osil. They additionally referenceassertalmost everywhere, plus twoNDEBUG-only sites, which I left alone:stdoutinsideassert()insepa_flower.candabort()inintervalarith.c.Symbols for a check in your CI
These are the C and C++ rows of R's table (
tools:::so_symbol_names_table), dumped from R on each platform. CRAN reports an object file if any of these names is among its undefined symbols (nm -Pg, typeU)._exit__exit_exit_exit_Exit__Exit,__exit_Exit_Exitabort_abortabortabortassert___assert_rtn__assert_fail_base__assert_fail_baseexit_exitexitexitprintf_printf,_putsprintf,__printf_chk,putsprintf,__printf_chk,putsputchar_putcharputcharputcharputs_putsputsputsrand_randrandrandrand_r_rand_rrand_rrand_rrandom_randomrandomrandomsprintf_sprintf,___sprintf_chksprintf,__sprintf_chksprintf,__sprintf_chksrand_srandsrandsrandsrand48_srand48srand48srand48srandom_srandomsrandomsrandomsrandom_rsrandom_rsrandom_rstderr___stderrpstderrstderrstdout___stdoutpstdoutstdoutvprintf_vprintfvprintf,__vprintf_chkvprintf,__vprintf_chkvsprintf_vsprintf,___vsprintf_chkvsprintf,__vsprintf_chkvsprintf,__vsprintf_chkstd::cerr__ZNSt3__14cerrE_ZSt4cerr,_ZNSt3__14cerrE_ZSt4cerr,_ZNSt3__14cerrEstd::cout__ZNSt3__14coutE_ZSt4cout,_ZNSt3__14coutE_ZSt4cout,_ZNSt3__14coutENotes for such a check:
printfintoputs/putcharand, with_FORTIFY_SOURCE, into__printf_chk(gcc) or__vprintf_chk(clang), so the check has to look atnmoutput, not at the sources.fputs/fprintf/fflushon aFILE*that was passed in are not on the list; namingstdout/stderris.assertis on the list, so the check should use a build withNDEBUG(CMake's default Release type). All builds above are Release builds unless marked Debug.CUSTOMIO, the expected result for libscip today is the objects listed under "Not changed".Base:
master. The touched files differ little betweenmasterandv10-minor, so I can retarget tov10-minorif you would rather have it in 10.2.