Infinite recursion with operator<<
Hello!
I noticed a crash when printing to stdout just by including <serdepp/serde.hpp>:
#include <iostream>
#include <serdepp/serde.hpp>
int main(int argc, char* argv[]) {
if (argc > 1) {
std::cout << argv[1] << std::endl;
}
return 0;
}
gcc emits the following warning:
In file included from ../include/serdepp/serde.hpp:8,
from ../test.cc:2:
../include/serdepp/ostream.hpp: In function ‘std::basic_ostream<_CharT, _Traits>& serde::ostream::operator<<(std::basic_ostream<_CharT, _Traits>&, const T&) [with CharT = char; Traits = std::char_traits<char>; T
= char*]’:
../include/serdepp/ostream.hpp:18:40: warning: infinite recursion detected [-Winfinite-recursion]
18 | std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT,Traits>& os, const T& x) {
| ^~~~~~~~
../include/serdepp/ostream.hpp:22:23: note: recursive call
22 | return os << x;
| ~~~^~~~
which, by reading the code, is exactly what happens at runtime in my example, hence the crash.
Could you provide additional information about the environment in which you built it?
My source layout is the following:
.
├── include
│ ├── magic_enum.hpp
│ ├── magic_enum_all.hpp
│ ├── magic_enum_containers.hpp
│ ├── magic_enum_flags.hpp
│ ├── magic_enum_format.hpp
│ ├── magic_enum_fuse.hpp
│ ├── magic_enum_iostream.hpp
│ ├── magic_enum_switch.hpp
│ ├── magic_enum_utility.hpp
│ ├── nameof.hpp
│ └── serdepp
│ ├── adaptor
│ │ ├── fmt.hpp
│ │ ├── nlohmann_json.hpp
│ │ ├── rapidjson.hpp
│ │ ├── reflection.hpp
│ │ ├── sstream.hpp
│ │ ├── toml11.hpp
│ │ └── yaml-cpp.hpp
│ ├── attribute
│ │ ├── algorithm.hpp
│ │ ├── default.hpp
│ │ ├── flatten.hpp
│ │ ├── make_optional.hpp
│ │ ├── meta.hpp
│ │ ├── mutli_key.hpp
│ │ ├── skip.hpp
│ │ ├── string_convert.hpp
│ │ └── value_or_struct.hpp
│ ├── attributes.hpp
│ ├── exception.hpp
│ ├── meta.hpp
│ ├── ostream.hpp
│ ├── serde.hpp
│ ├── serializer.hpp
│ └── utility.hpp
├── meson.build
└── test.cc
I am using the main branch of serdepp (commit 2682b8d586a8c07a7826211ea66087ac841bbc12), magic_enum 0.9.5 and nameof 0.10.3.
g++ version:
g++ (Ubuntu 13.1.0-8ubuntu1~22.04) 13.1.0
g++ commands invoked by ninja:
c++ -ITest.p -I. -I.. -I../include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++23 -O0 -g -MD -MQ Test.p/test.cc.o -MF Test.p/test.cc.o.d -o Test.p/test.cc.o -c ../test.cc
c++ -o Test Test.p/test.cc.o -Wl,--as-needed -Wl,--no-undefined
It seems to be a bug in serdepp. It looks like we need to implement it in a different way than the current approach in ostream.hpp.
If you want to use it before I patch the bug, you can comment out the following section in the code:
https://github.com/injae/serdepp/blob/2682b8d586a8c07a7826211ea66087ac841bbc12/include/serdepp/serde.hpp#L8
After commenting out that part, you can use it like this:
std::cout << serialize<serde::serde_sstream>(x).str() << std::endl;
Thank you for reporting the bug. 👍