Nicht einfach zu sagen, was meine Programmierfrage ist, da ich nicht wirklich sehe, wo das Problem liegt. Tatsächlich habe ich einen Laufzeitfehler irgendwo in der Boost Spirit Karma Library verloren. Ich denke, ich vermisse hier eine Debugging-Technik.Welche Debugging-Technik für einen Karma-Generator mit Laufzeitfehler
habe ich, dass das Makro BOOST_SPIRIT_DEBUG_NODE (S) für Parser hilft sehr zu sehen, obwohl ich nicht einen Hinweis auf mich im Handbuch finden. Für Generatoren scheint es, dass dies nicht funktioniert und ich (ehrlich gesagt) nicht den Mut habe (sollte ich?), Den Code dieser Bibliothek zu durchforsten, um zu verstehen, wo das Problem liegt.
Ich habe versucht, die drei Arten meiner unionartigen Struktur allein in einer Grammatik ohne irgendein Problem zu erzeugen. Also ich vermute der Fehler kommt von der Besetzung der U-Struktur in eine Boost-Variante, nochmal (siehe Casting attribute to boost::variant) aber ich habe keinen Beweis.
Für diejenigen, die es mit einem einfachen Code-Inspektion lösen könnte, hier ist die minimale Beispiel meiner Frage:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/karma.hpp>
#include <boost/variant/variant.hpp>
namespace ka = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> iterator;
typedef enum {A, B, C } E;
typedef enum {FOO, BAR, POINTER } K;
struct U /* Union like */
{
K kind;
double foo;
E bar;
unsigned int * p;
};
class EName : public ka::symbols<E, std::string>
{
public:
EName()
{
add (A,"A") (B,"B") (C,"C");
}
};
typedef boost::variant<E, double, unsigned int *> UVariant;
namespace boost { namespace spirit { namespace traits {
template<>
struct transform_attribute<const U,UVariant,ka::domain>
{
typedef UVariant type;
static type pre(const U & u) {
switch (u.kind)
{
case FOO:
return type(u.foo);
case BAR:
return type(u.bar);
case POINTER:
return type(u.p);
}
return type(A);
}
};
}}}
class grm: public ka::grammar<iterator, U()>
{
public:
grm():grm::base_type(start)
{
start = ka::attr_cast<UVariant >(bar | foo | pointer);
bar = b;
foo = ka::double_;
pointer = ka::hex;
}
private:
ka::rule<iterator,U()> start;
ka::rule<iterator,double()> foo;
ka::rule<iterator,E()> bar;
ka::rule<iterator,unsigned int *()> pointer;
EName b;
};
int main(int argc, char * argv[])
{
grm g;
U u;
//unsigned int a;
u.kind = BAR;
//u.foo = 1.0;
u.bar = B;
//u.p = &a;
std::string generated;
std::back_insert_iterator<std::string> sink(generated);
ka::generate(sink,g,u);
std::cout << generated;
return 0;
}
UPDATE: Compiler: Visual C++ Express-Version 11 und 12. Die Call-Stack Anschläge an:
// If you are seeing a compilation error here stating that the
// third parameter can't be converted to a karma::reference
// then you are probably trying to use a rule or a grammar with
// an incompatible delimiter type.
if (f(sink, context, delim)) // <--- call stack stops here (last boost spirit reference)
auch habe ich herausgefunden, dass die Definition des _SCL_SECURE_NO_WARNINGS Makro die folgende Compiler-Warnung beschattete:
Warnung C4996: ‚std :: _ Copy_impl‘: Funktionsaufruf mit Parametern, die unsicher sein könnte - dieser Aufruf stützt sich auf den Anrufer zu überprüfen, ob die gebenen Werte korrekt sind. Verwenden Sie -D_SCL_SECURE_NO_WARNINGS, um diese Warnung zu deaktivieren. Siehe Dokumentation, wie Visual C++ verwenden 'aktiviert Iteratoren'
Diese Warnung unter Bezugnahme auf mehrere Boost-Geist-Dateien:
- Geist \ home \ Karma \ Detail \ output_iterator.hpp (242)
Geist \ home \ Karma \ Detail \ output_iterator.hpp (577)
Geist \ home \ Karma \ Detail \ output_iterator.hpp (574)
Geist \ home \ Karma \ Detail \ alternative_function.hpp (170)
Geist \ home \ karma \ detail \ alternative_funktion.hpp (162)
spirit \ home \ karma \ Operator \ alternative.hpp (122)
spirit \ Home \ karma \ Hilfs \ attr_cast.hpp (85)
spirit \ home \ karma \ nicht terminale \ Detail \ generator_binder.hpp (43)
Geist \ home \ Karma \ Nicht-End \ Detail \ generator_binder.hpp (52)
Geist \ home \ Karma \ Nicht-End \ rule.hpp (193)
Geist \ home \ Karma \ Nicht-End \ rule.hpp (230)
"Ich habe einen Laufzeitfehler" - was ist das? Ich kann das nicht reproduzieren. Debugging-Technik # 1 ist die verfügbaren Fakten zu beobachten. – sehe
Ich denke, ich habe gerade eine glückliche Gehirnwelle, siehe meine Antwort – sehe