boostorg / pfr

std::tuple like methods for user defined types without any macro or boilerplate code

Home Page:https://boost.org/libs/pfr

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

error: variable 'boost::pfr::detail::fake_object<Test>' is used but not defined

linuxnyasha opened this issue · comments

In file included from error.cpp:1:
In file included from /usr/include/boost/pfr.hpp:14:
In file included from /usr/include/boost/pfr/core_name.hpp:17:
In file included from /usr/include/boost/pfr/detail/core_name.hpp:23:
In file included from /usr/include/boost/pfr/detail/core_name20_static.hpp:21:
/usr/include/boost/pfr/detail/fake_object.hpp:20:16: error: variable 'boost::pfr::detail::fake_object' 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
20 | extern const T fake_object;
| ^
error.cpp:7:29: note: used here
7 | (void)boost::pfr::detail::fake_object;
| ^

#include <boost/pfr.hpp>

int main() {
  struct Test {
    int data;
  };
  (void)boost::pfr::detail::fake_object<Test>;
};

fake_object is intentionally designed to be devoid of linkage, signifying its exclusive purpose for member name retrieval. It serves as a companion to declval<T>() by providing a compile-time "memory address" without actual utilization.

This behavior is not a defect, as long as the object remains encapsulated within the detail namespace.
However, it becomes a bug if the error can be replicated without explicitly using fake_object.

#include <boost/pfr.hpp>
int main() {
  struct Test {
    int field;
  };
  static_assert(boost::pfr::get_name<0, Test>() == "field");
};

Could you please provide details about the operating system, compiler (including version), and toolchain you are using? I am facing challenges in replicating the issue, and automated tests are yielding positive results. It's possible that the issue may be specific to your environment.

Gentoo Linux

clang --version
clang version 17.0.4
Target: x86_64-gentoo-linux-musl
Thread model: posix
InstalledDir: /usr/lib/llvm/17/bin
Configuration file: /etc/clang/x86_64-gentoo-linux-musl-clang.cfg

Can you show me a test that worked successfully? I didn't find one. Error on g++-13 (Gentoo 13.2.1_p20231014 p10) 13.2.1 20231014:

In file included from /usr/include/boost/pfr/detail/core_name20_static.hpp:21,
                 from /usr/include/boost/pfr/detail/core_name.hpp:23,
                 from /usr/include/boost/pfr/core_name.hpp:17,
                 from /usr/include/boost/pfr.hpp:14,
                 from lu.cpp:1:
/usr/include/boost/pfr/detail/fake_object.hpp:20:16: error: ‘const main()::Test boost::pfr::detail::fake_object<main()::Test>’, declared using local type ‘const main()::Test’, is used but never
defined [-fpermissive]
   20 | extern const T fake_object;

The limitation says that

The Boost.PFRs extraction of field name has some limitations that depend on a C++ Standard and compiler capabilities:
T should be usable like extern T t;, i.e. has a non-internal linkage.

Function local classes has no external linkage, so it will not work with those structures.


The tests can be found here, and the tests are run in GitHub actions, like here

Hi @denzor200 ,

Is it possible to rename the fake_object or create a pre-checker object with a more meaningful name, such as passed_type_has_no_external_linkage with some comment? This would enhance the clarity of error messages.

Hi, @schaumb ,

Sure, PR will be created in the future

Here is the PR: #146