using yaml-cpp with pointers in C++

Started by
2 comments, last by 3dmodelerguy 5 years, 10 months ago

So I am trying to using Yaml as my game data files (mainly because it support comments, is a bit easier to read than JSON, and I am going to be working in these files a lot) with C++ and yaml-cpp (https://github.com/jbeder/yaml-cpp) seems like the most popular library for dealing with it however I am running into an issue when using pointers.

Here is my code:


struct InventoryItem {
  std::string name;
  int baseValue;
  float weight;
};

struct Inventory {
  float maximumWeight;
  std::vector<InventoryItem*> items;
};

namespace YAML {
template <>
struct convert<InventoryItem*> {
  static Node encode(const InventoryItem* inventoryItem) {
    Node node;

    node["name"] = inventoryItem->name;
    node["baseValue"] = inventoryItem->baseValue;
    node["weight"] = inventoryItem->weight;

    return node;
  }

  static bool decode(const Node& node, InventoryItem* inventoryItem) {
    // @todo validation
    inventoryItem->name = node["name"].as<std::string>();
    inventoryItem->baseValue = node["baseValue"].as<int>();
    inventoryItem->weight = node["weight"].as<float>();

    return true;
  }
};

template <>
struct convert<Inventory> {
  static Node encode(const Inventory& inventory) {
    Node node;

    node["maximumWeight"] = inventory.maximumWeight;
    node["items"] = inventory.items;

    return node;
  }

  static bool decode(const Node& node, Inventory& inventory) {
    // @todo validation
    inventory.maximumWeight = node["maximumWeight"].as<float>();
    inventory.items = node["items"].as<std::vector<InventoryItem*>>();

    return true;
  }
};
}

if I just did `std::vector<InventoryItem> items` and had the encode / decode use `InventoryItem& inventoryItem` everything works fine however when I use the code above that has it as a pointer, I get the following error from code that is part of the yaml-cpp library:


impl.h(123): error C4700: uninitialized local variable 't' used

The code with the error is:


template <typename T>
struct as_if<T, void> {
  explicit as_if(const Node& node_) : node(node_) {}
  const Node& node;

  T operator()() const {
    if (!node.m_pNode)
      throw TypedBadConversion<T>(node.Mark());

    T t;
    if (convert<T>::decode(node, t)) // NOTE: THIS IS THE LINE THE COMPILER ERROR IS REFERENCING
      return t;
    throw TypedBadConversion<T>(node.Mark());
  }
};

With my relative lack of experience in C++ and not being able to find any documentation for yaml-cpp using pointers, I am not exactly sure what is wrong with my code.

Anyone have any ideas what I need to change with my code? 

Advertisement

One line before the compiler error happens, the code created an item of type T. In your case, that is an InventoryItem *, which is unintialized by default. It is just a pointer and has no object associated with it. Your code actually assumes that it contains a valid object and dereferences the pointer that points into nothingness, hence the error.

You should either use:


static bool decode(const Node& node, InventoryItem*& inventoryItem) {
  inventoryItem = new InventoryItem();
  inventoryItem->name = node["name"].as<std::string>();
  // .. etc ..
}

or consider not using the pointers.

@DaBono Thanks for pointing out what was happening here as it now makes sense why this was my issue (I guess I should have looked at the libraries code closer).

This topic is closed to new replies.

Advertisement