veselink1/refl-cpp

Compilation error with simple example

Matheus-Garbelini opened this issue · 7 comments

Hi, I was trying to perform a simple example but I am receiving a lot of errors during compilation.
I'm using gcc/g++ 8.4.0 and compiling the program with the following command:
g++ -std=c++17 -Wall -g main.cpp -o test

#define REFL_METADATA_FILE "reflmd/main.cpp"
#include "libs/refl.hpp"
#include <iostream>

struct pdu_types_struct
{
    REFL() // the reflmd file has been generated
    int var1= 28;
};

struct pdu_types_struct pdu_types;

int main(int argc, char **argv)
{
     for_each(refl::reflect(pdu_types).members, [&](auto member) {
      std::cout << member.name << "=" << member(pdu_types) << ";";
   });
    return 0;
} 

#include REFL_METADATA_FILE

With the code above, I receive the following errors:

g++ -std=c++17 -Wall -g main.cpp -o test   
In file included from main.cpp:2:
libs/refl.hpp: In instantiation of ‘class refl::descriptor::type_descriptor<pdu_types_struct>’:
main.cpp:15:38:   required from here
libs/refl.hpp:1625:27: error: static assertion failed: This type does not support reflection!
             static_assert(refl::trait::is_reflectable_v<T>, "This type does not support reflection!");
                           ^~~~
libs/refl.hpp:2620:55: error: specialization of ‘refl_impl::metadata::type_info__<pdu_types_struct>’ after instantiation
     namespace refl_impl::metadata { template<> struct type_info__<TypeName> { \
                                                       ^~~~~~~~~~~~~~~~~~~~~
reflmd/main.cpp:3:1: note: in expansion of macro ‘REFL_TYPE’
 REFL_TYPE(pdu_types_struct)
 ^~~~~~~~~
libs/refl.hpp:2620:55: error: redefinition of ‘struct refl_impl::metadata::type_info__<pdu_types_struct>’
     namespace refl_impl::metadata { template<> struct type_info__<TypeName> { \
                                                       ^~~~~~~~~~~~~~~~~~~~~
reflmd/main.cpp:3:1: note: in expansion of macro ‘REFL_TYPE’
 REFL_TYPE(pdu_types_struct)
 ^~~~~~~~~
In file included from main.cpp:2:
libs/refl.hpp:373:20: note: previous definition of ‘struct refl_impl::metadata::type_info__<pdu_types_struct>’
             struct type_info__

Is there some pre step to use the library I am missing or some additional argument when calling g++?

Regards

Hello,

I assume you are running refl-ht -input=main.cpp beforehand? The preprocessor hasn't been updated to work with recent refl-cpp versions as there are some issues which cannot be solved without rewriting the whole thing are creating more work than I can manage at the moment.

I would suggest that you go the usual route of using REFL_AUTO or the REFL_TYPE/FIELD macros as that is currently fully supported.
In your case you would need to remove the REFL_METADATA_FILE and REFL() lines and add something like the following after the struct definition.

REFL_AUTO(
    type(pdu_types_struct),
    field(var1)
)

@veselink1 thanks for your reply. I was indeed using refl-ht beforehand.
using the REFL_AUTO instead of the refl-ht preprocessor worked fine.
However, the file that refl-ht seems to be fine. It generates a main.cpp like this:

REFL_TYPE(pdu_types_struct)
REFL_FIELD(var1)
REFL_END

If I use the old refl-cpp style and copy this block in my code, it works fine.
For some reason, just by including this on a separate file seems to be generating all these errors. By digging further, I was able to confirm that just by placing the REFL reflection definition on bottom of the source code, we receive many errors such as "This type does not support reflection".

In short, this does not work:

#include "libs/refl.hpp"
#include <iostream>

struct pdu_types_struct
{
    int var1= 28;
};

struct pdu_types_struct pdu_types;

int main(int argc, char **argv)
{
     for_each(refl::reflect(pdu_types).members, [&](auto member) {
      std::cout << member.name << "=" << member(pdu_types) << ";" << std::endl;
   });
    return 0;
} 

REFL_AUTO(
    type(pdu_types_struct),
    field(var1)
)

But this works:

#include "libs/refl.hpp"
#include <iostream>

struct pdu_types_struct
{
    int var1= 28;
};

REFL_AUTO(
    type(pdu_types_struct),
    field(var1)
)

struct pdu_types_struct pdu_types;

int main(int argc, char **argv)
{
     for_each(refl::reflect(pdu_types).members, [&](auto member) {
      std::cout << member.name << "=" << member(pdu_types) << ";" << std::endl;
   });
    return 0;
} 

Nevertheless, I'm using the last option. Thanks a lot for this project.

Just chaining another question. What is the simplest way (low overhead) to get a member name to a string or preferable a char array (char *)?
Currently, I'm only able to get a string to making this costly operation inside the foreach loop:

 stringstream s("");
 s << member.name;

I've tried assigning the member name directly to a string object but it gave me errors.

Thank you for taking the time to look into what the specific issue is. That seems to be happening because the template-specializations created by the REFL_AUTO macro are not available at the point of usage in main(). Reflection information should ideally be defined right after the type definition.

member.name is of type refl::util::const_string. To get a const char* from a const_string<N> one could use const_string::c_str().

I'm closing this as refl-ht has been discontinued.