Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Basic tests fail with msvc but work with gcc

I have a simple setup. My base class is:

class PartBase {
  private:
    std::string_view m_Name;


  public:
    explicit PartBase(std::string_view name)
        : m_Name(name){};

    std::string_view getName() { return m_Name; };

    void build() {
        std::cout << "Started building " << getName() << "\n";
        buildPart();
        std::cout << "Building " << getName() << " completed.\n";
    }

    virtual void buildPart(){};
};

Then I have two classes one level higher:

class Rib : public PartBase {
  public:
    explicit Rib(const std::string& partName)
        : PartBase(partName){};

    void buildPart() override {
        std::cout << "Started building " << getName() << "\n";
    };
};

and

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class Wing : public PartBase {
  private:
    std::vector<Rib> m_Ribs;

  public:
    explicit Wing(const std::string& partName, spdlog::logger& logger)
        : PartBase(partName, logger){};

    void buildPart() override {
        std::cout << "Started building " << getName() << "\n";
    };
};

Then I have a dumb catch2 test that simply creates a class.

TEST_CASE("WingPartTests", "[tests_wing]") {
    SECTION("test_wing_creation ") {
        // Check creation.
        REQUIRE_NOTHROW(Wing("abc"));

        // Get wing name.
        auto wing = Wing("abc");
        REQUIRE(wing.getName() == "abc");
    }
}

The problem

The problem is that this test passes on Linux with gcc (c++20) no problem. It also builds on msvc, but the tests don’t pass. The test fails with the following output:

7: ..... test\parts\test_wing.cpp(21): FAILED:
7:   REQUIRE( wing.getName() == "abc" )
7: with expansion:
7:   "
7: bc" == "abc"

This I guess makes the test not so "dumb" after all, but I have to admit I have no idea what the problem is. I work on linux, so the only output I get is from the CI. Would anybody know?

>Solution :

You are creating std::string_view with a temporary object that is destroyed when the constructor finishes. It is equivalent to this:

int main() {
    auto wing = std::string_view(std::string("abc"));
    
    // Prints "bc" on Visual Studio
    std::cout << wing << std::endl; 
}

This does not work, as string_view is a simple pointer that does not extend the lifetime of the data:

A typical implementation holds only two members: a pointer to constant CharT and a size.

Change the type of m_Name to std::string to copy the data.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading