reflect-cpp: Reflection for structs in an anoynoumus namespace results in compilation errors
When rfl is being used on a struct in an anonymous namespace,
gcc complains at linkage stage with errors like:
/usr/bin/ld: src/.../tests.cpp.o: warning: relocation against `_ZN3rfl8internal11fake_objectIN12_GLOBAL__N_13ABCEEE' in read-only section `.text'
/usr/bin/ld: src/.../tests.cpp.o: in function `auto rfl::internal::get_field_names<(anonymous namespace)::DEF>()':
/home/...//include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x2950): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::DEF>'
/usr/bin/ld: /home/.../include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x295b): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::DEF>'
/usr/bin/ld: src/.../tests.cpp.o: in function `auto rfl::internal::get_field_names<(anonymous namespace)::ABC>()':
/home/.../include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x33fb): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::ABC>'
/usr/bin/ld: /home/.../include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x3406): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::ABC>'
/usr/bin/ld: /home/.../include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x3411): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::ABC>'
/usr/bin/ld: /home/.../include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x341c): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::ABC>'
/usr/bin/ld: /home/.../include/rfl/internal/../internal/get_field_names.hpp:120:(.text+0x3427): undefined reference to `rfl::internal::fake_object<(anonymous namespace)::ABC>'
/usr/bin/ld: src/.../tests.cpp.o:/home/.../include/rfl/internal/../internal/get_field_names.hpp:120: more undefined references to `rfl::internal::fake_object<(anonymous namespace)::ABC>' follow
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
and clang throws erros at compilation time:
/home/.../include/rfl/internal/fake_object.hpp:9:10: error: variable 'rfl::internal::fake_object<(anonymous namespace)::DEF>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
About this issue
- Original URL
- State: closed
- Created 6 months ago
- Comments: 16 (9 by maintainers)
Commits related to this issue
- Added test for unnamed_namespace (remarkably, it runs through in GCC); #46 — committed to getml/reflect-cpp by deleted user 6 months ago
- Minor modification to fake_object that apparently fixes #46 — committed to getml/reflect-cpp by deleted user 6 months ago
- Implemented better solution for #46 — committed to getml/reflect-cpp by deleted user 6 months ago
- Implemented a solution for #46 that will also work on MSVC — committed to getml/reflect-cpp by deleted user 6 months ago
- Made sure that we can get field names from structs declared inside functions or unnamed namespaces; #46 — committed to getml/reflect-cpp by deleted user 6 months ago
- Added missing header; #46 — committed to getml/reflect-cpp by deleted user 6 months ago
Another note for the solution: Probably it would have been easier if the
template externvariable was put in an anonymous namespace. (last block:)you can force MSVC to “not use” the symbol if it is used only in template arguments. https://godbolt.org/z/bWfTTvqo3
I think this is not a bug because later it can be defined in this compilation unit. And because no one uses it, it shouldn’t be a linker error. But I could not argue with my statement.
If you are afraid that
template extern wrapper<T>is not what you want to use because ofexternan internal linkage class, replace it with template struct static member. This technique is much older, and no one found this to be problematic. (the definition is inside the class, and the declaration is nowhere)Note: If you want to use static assertion on types, you must check unnamed classes too.
@schaumb , you are right, of course. Thanks for the input on how to fix it. By the way, I love your work on Boost.PFR.