[C++] antlrcpp::Any incorrect behavior when storing std::string
See original GitHub issueThe antlrcpp::Any
class does not properly handle storing std::string types in copy constructor/assignment. For example, this code:
#include <iostream>
#include <string>
#include "antlr4-runtime.h"
int main()
{
antlrcpp::Any a = std::string("hello");
antlrcpp::Any b = a;
std::cout << "a = ";
if (a.isNotNull()) {
if (a.is<std::string>()) {
std::cout << a.as<std::string>() << "\n";
}
} else {
std::cout << "null\n";
}
std::cout << "b = ";
if (b.isNotNull()) {
if (b.is<std::string>()) {
std::cout << b.as<std::string>() << "\n";
}
} else {
std::cout << "null\n";
}
return 0;
}
Would be expected to print (and does if changed to use std::any):
a = hello
b = hello
However b does not get assigned the correct value from a and the above code actually prints:
a = hello
b = null
Wrapping the std::string in a pointer like std::shared_ptr yields the expected behavior; however it seems like the condition on clone in Any is too restrictive:
template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
Base* clone() const {
return new Derived<T>(value);
}
In looking into this I noticed that Boost’s Any actually has no restriction applied, which makes sense to me in terms of cloning any type to itself that is copy/move/etc constructible:
virtual placeholder * clone() const
{
return new holder(held);
}
So could clone in Any just become this?
Base* clone() const {
return new Derived<T>(value);
}
I changed this in my local build and it fixes the original issue, but I’m not sure if this has some potential side effects since I’m testing in a small codebase. If it seems ok, I can make this change and open a PR
Issue Analytics
- State:
- Created 2 years ago
- Reactions:5
- Comments:14 (6 by maintainers)
Top GitHub Comments
Yeah this can be closed, I ran into an issue testing it where ANTLR 4.9.3 still generates some older/removed members for some classes that have been removed in master so it hits some other non-any compile issue. However moving to std::any will fix the initial issue so I’ll close this, and will try it out in 4.9.4. Thanks for fixing it @jcking !
That’d be great, unfortunately I’ve been pretty buried the past month and haven’t been able to push that along.