-1

So I am trying to use yaml-cpp with data that contains 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;
  }
};
}

But I am getting the following error:

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

Which is referencing the last if statement in this code block (this code is in teh yaml-cpp library:

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());
  }
};

Does anyone know why I might be getting this error?

ryanzec
  • 27,284
  • 38
  • 112
  • 169
  • then you just need to `dereference` each `item`, which is a `pointer` of type `Inventory`, and pass it to `decode` – Joseph D. Jun 12 '18 at 00:32
  • @codekaizer I don't manually call encode / decode, from my understanding that is something that the yaml-cpp library calls so I don't know if (or how) I would be able to do that – ryanzec Jun 12 '18 at 09:17
  • Have you tried [ThorsSerializer](https://github.com/Loki-Astari/ThorsSerializer) looks like it would be a lot simpler. You don't actually need to write any code. https://gist.github.com/Loki-Astari/0363c54fcd3db0a144e58e91ee6e0f01 – Martin York Jul 16 '18 at 06:26
  • Oops Missed the pointer thing. Are you sure you need that? Unless `InventoryItem` is polymorphic that seems overkill. – Martin York Jul 16 '18 at 06:53

1 Answers1

0

Based on an answer from gamedev.net the issue is that my decode needs to look like this:

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

  return true;
}

This is becausethe yaml-cpp library code just declares the the variable with T t; which in the case of a pointer type means it is uninitialized (for normal values, it is initialized by the default constructor).

ryanzec
  • 27,284
  • 38
  • 112
  • 169
  • 1
    This is a memory leak. You never delete the InventoryItem allocated at the start of the function and don't have a reference to the pointer to delete it after the function returns. – user1593858 Jun 17 '18 at 13:18