Bug #4569

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

Added by Junxiao Shi about 1 year ago. Updated 3 months 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 3 months 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 3 months 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 3 months 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