monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] prompt diagnosis of missing dump() instantiations


From: Zack Weinberg
Subject: [Monotone-devel] prompt diagnosis of missing dump() instantiations
Date: Tue, 25 Jul 2006 11:00:27 -0700

Right now if you MM() something for which there is no dump()
specialization, the file compiles fine and then you get a link error.
This is annoying because it takes a really long time to link monotone
*even if the link fails*.

The appended patch, which I have gone ahead and put on mainline,
causes a compile-time error instead.  It looks like this:

vocab.hh: In function 'void dump(const T&, std::string&) [with T =
unsigned int]':
sanity.hh:464:   instantiated from 'void Musing<T>::gasp(std::string&) const
[with T = unsigned int]'
monotone.cc:707:   instantiated from here
vocab.hh:35: error: invalid application of 'sizeof' to incomplete type
'dump_must_be_specialized_for_this_type'

[I put a dummy MM() in cpp_main to ensure that it worked.]  This
actually caught a quasi-bug -- roster.hh wasn't declaring the
dump(std::set<revision_id>) specialization as a specialization, but as
an unrelated overload, so a use of MM(set<revision_id>) in
roster_merge.cc blew up.

zw

        * vocab.hh: Provide base definition of dump template which
        generates a compile-time error if ever instantiated.
        * roster.hh: Correct declaration of dump<set<revision_id>>
        specialization.
#
# old_revision [682827d5cd13fb9b7b3e7ea186bdadd7865cfabf]
#
# patch "roster.hh"
#  from [49ce9f36b5f507091d99d4889e04fd231275029c]
#    to [e9af7013444ae886984161273fae5e896c992738]
#
# patch "vocab.hh"
#  from [97df5261da082ee26027f1a933552ad67a1deda8]
#    to [9c9abcf5283f4d0a4fdc7d1d1751b0617ec7ecc5]
#
============================================================
--- roster.hh   49ce9f36b5f507091d99d4889e04fd231275029c
+++ roster.hh   e9af7013444ae886984161273fae5e896c992738
@@ -164,7 +164,7 @@

typedef std::map<node_id, marking_t> marking_map;

-void dump(std::set<revision_id> & revids, std::string & out);
+template <> void dump(std::set<revision_id> const & revids, std::string & out);
template <> void dump(marking_t const & marking, std::string & out);
template <> void dump(marking_map const & marking_map, std::string & out);

============================================================
--- vocab.hh    97df5261da082ee26027f1a933552ad67a1deda8
+++ vocab.hh    9c9abcf5283f4d0a4fdc7d1d1751b0617ec7ecc5
@@ -21,8 +21,19 @@
// generally describe the "vocabulary" (nouns anyways) that modules in this
// program use.

+// this template must be specialized for each type you want to dump.
+// there are a few stock dumpers in appropriate places.
template <typename T>
-void dump(T const &, std::string &);
+void dump(T const &, std::string &)
+{
+  // the compiler will evaluate this somewhat odd construct (and issue an
+  // error) if and only if this base template is instantiated.  we do not
+  // use BOOST_STATIC_ASSERT mainly to avoid dragging it in everywhere;
+  // also we get better diagnostics this way (the error tells you what is
+  // wrong, not just that there's an assertion failure).
+  enum dummy { d = (sizeof(struct dump_must_be_specialized_for_this_type)
+                   == sizeof(T)) };
+}

#include "vocab_macros.hh"
#define ENCODING(enc) hh_ENCODING(enc)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]