question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[C++] antlrcpp::Any incorrect behavior when storing std::string

See original GitHub issue

The 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:closed
  • Created 2 years ago
  • Reactions:5
  • Comments:14 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
Twinklebearcommented, Dec 29, 2021

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 !

1reaction
Twinklebearcommented, Oct 12, 2021

That’d be great, unfortunately I’ve been pretty buried the past month and haven’t been able to push that along.

Read more comments on GitHub >

github_iconTop Results From Across the Web

C++ strange behavior with string's c_str() function
What's happening in the invalid case is that GetTheStr() is returning a temporary, then c_str() is returning a reference to its internal ...
Read more >
[Solved]-C++ Incorrect behavior of std::string initialization-C++
This is undefined behavior. This is invoking a constructor of std::string that accepts two iterators, the beginning and the ending iterator value.
Read more >
4.3. Storing Strings in a Sequence - C++ Cookbook [Book]
Problem. You want to store a set of strings in a sequence that looks and feels like an array.
Read more >
std::tolower - cppreference.com
Converts the given character to lowercase according to the character conversion rules defined by the currently installed C locale.
Read more >
char* vs std:string vs char[] in C++ - GeeksforGeeks
We can change str to point something else but cannot change value present at str. Refer storage-for-strings-in-c for more detail.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found