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

Most upvoted comments

Another note for the solution: Probably it would have been easier if the template extern variable was put in an anonymous namespace. (last block:) kép

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 of extern an 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.