Bug #4569

Default-constructed MetaInfo does not equal MetaInfo decoded with default values

Added by Junxiao Shi 11 months ago. Updated 26 days ago.

Target version:
Start date:
Due date:
% Done:


Estimated time:
1.00 h


Snippet to reproduce:

// g++ -std=c++11 -o x x.cpp $(pkg-config --cflags --libs libndn-cxx)

#include <iostream>

#include <ndn-cxx/encoding/block.hpp>
#include <ndn-cxx/meta-info.hpp>

  static uint8_t WIRE[] = { 0x14, 0x03, 0x18, 0x01, 0x00 };
  ndn::MetaInfo a(ndn::Block(WIRE, sizeof(WIRE)));
  ndn::MetaInfo b;
  std::cout << static_cast<int>(a == b) << std::endl;
  return 0;

Expected: program prints 1, indicating a equals b.
Actual: program prints 0, indicating a does not equal b.


#1 Updated by Junxiao Shi about 1 month ago

With Packet03Transition permitting unrecognized non-critical TLV elements, this problem becomes acuter: what does operator== mean for an object that represents a TLV element?
It could be defined as either:

  • Equality of semantics. Under this choice, MetaInfo("1400"_block) equals MetaInfo("1403 180100"_block) because they are semantically equivalent: the former omits ContentType and accepts its default value, while the latter includes ContentType with the default value.
  • Equality of TLV encoding, excluding unrecognized elements. Under this choice, MetaInfo("1400"_block) does not equal MetaInfo("1403 180100"_block). MetaInfo("1403 180100"_block) equals MetaInfo("1405 F000 180100"_block) where F000 is ignored.
  • Equality of TLV encoding, including unrecognized elements. Under this choice, MetaInfo("1400"_block) and MetaInfo("1403 180100"_block) and MetaInfo("1405 F000 180100"_block) do not equal one another, despite they all have the same semantics.

This would be a design choice of ndn-cxx library and should be applied to all network-layer TLV element classes in the library. It is not a protocol design question.

#2 Updated by Alex Afanasyev 27 days ago

In my opinion, it should be the third option (I believe it is now). Semantics is kind of irrelevant here, as you cannot interpret the semantics of application-defined elements.

As for the behavior. I think it is fine as is. It's basically a spec problem. The default value should not have had the explicit encoding, as it effectively has 2 different states representing the same thing.

#3 Updated by Davide Pesavento 26 days ago

There's also option 4: remove operator== and operator!= for these classes.
I doubt there are many use cases that require them, beyond low-level wire encoding comparison (essentially a memcmp) that can easily use Block's operators.

Also available in: Atom PDF