c++: dynamic_cast woes
- Reply: Mark Millard : "Re: c++: dynamic_cast woes"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 06 Aug 2023 21:40:00 UTC
Hi, while updating our kicad port I'm facing major problems with dynamic_cast on FreeBSD 13.2/amd64 - issues are seen with both base clang and devel/llvm15, and I guess we're rather talking libc++ here. Specifically, dynamic_cast fails when casting from a base to a derived type ("downcast" as in C++ lingo?). I already know about "--export-dynamic" but that does not help here - and as far as I read other platform's build scripts, no other platform requires any kind of "special handling" for dynamic_cast to work - what am I holding wrong here, or what's missing from the picture? But for the gory details: here's exhibit A, the code in question: https://gitlab.com/kicad/code/kicad/-/blob/7.0/include/settings/settings_manager.h?ref_type=heads#L110 That m_settings is declared as std::vector<std::unique_ptr<JSON_SETTINGS>> m_settings; and contains objects of types derived from JSON_SETTINGS (there's the intermediate type APP_SETTINGS_BASE, and specific types like KICAD_SETTINGS etc.) The function GetAppSettings<KICAD_SETTING>() is called, so that the find_if() in there should return that one KICAD_SETTINGS object from m_settings as only that should satisfy dynamic_cast - but in fact, no object is found. That also happens if I unwind the find_if() and build a simple for-loop (as one did, back in the last millenium). If I point gdb at that m_settings (with "set print object on" and "set print vtbl on"), I do find my KICAD_SETTINGS object smack in the middle of m_settings: (gdb) print *(m_settings[5]) $18 = (KICAD_SETTINGS) {<APP_SETTINGS_BASE> = {<JSON_SETTINGS> = { _vptr$JSON_SETTINGS = 0xed1578 <vtable for KICAD_SETTINGS+16>, so the type info isn't totally lost here. When testing this, CXXFLAGS passed via cmake are rather minimal, like "-std=c++17 -O0 -fstack-protector-strong -fno-strict-aliasing -Wl,--export-dynamic" (and cmake sprinkles some "-g" and a few other standard flags into the mix), LDFLAGS ("CMAKE_...LINKER_FLAGS") are set up similarly) (I have some inkling that these cmakefiles in this project are not always very strict on compiling vs linking). I had similar issues with dynamic_cast before, as witnessed here: https://cgit.freebsd.org/ports/tree/cad/kicad/files/patch-job_use_dynamic_cast_for_updating but now that I'm facing the current problem, I have a strong feeling that my diagnosis back than was rather bullshit. Help? Thanks, Christoph -- Spare Space