Stimmt's? C++ ist schwer zu parsen.



  • Stimmt's? schrieb:

    Koenig Lookup, partial template specialization, ...?

    Das fällt aber afaik in den Bereich der semantischen Analyse und nicht in den Bereich des Parsers.

    C++ ist glaube ich so schwer zu parsen, weil es viele Kontextabhängigkeiten gibt. So kann ein '<' Token zB ein Template einleiten oder ein Operator darstellen.

    Für interessierte, die BNF Gramatik von C++ (HCB = Hyperlinked C++ BNF Grammar)



  • relisoft schrieb:

    Apparently, VS uses a different (incomplete) parser for its browser than it does for its compiler, and that's probably why it can't deal with namespaces or nested classes.

    Kann ich bei VC++2003 nicht bestätigen.



  • Eines der Probleme wird der Preprozessor sein.

    Codebereiche durch #ifdef #else #endif ein oder auszublenden find ich extrem hässlich. Das das auch beim Parsen / analysieren von Code probleme machen kann sit wohl klar. Geschweigeden von Refectoring.

    Muss der aufruf angepasst werden oder nicht, wenn ich jetzt den Methodennamen ändern?

    In java hab ich das nicht. da gilt nur der code den ich sehe. und nicht vileicht doch wenn #define debug gesetzt ist ( geht ja auch über compiler parameter. -DNODBUG )

    Die trennung von hpp und cpp dateien verringert die probleme sicherlich nicht wirklich.

    gruss



  • rüdiger schrieb:

    Stimmt's? schrieb:

    Koenig Lookup, partial template specialization, ...?

    Das fällt aber afaik in den Bereich der semantischen Analyse und nicht in den Bereich des Parsers.

    C++ ist glaube ich so schwer zu parsen, weil es viele Kontextabhängigkeiten gibt. So kann ein '<' Token zB ein Template einleiten oder ein Operator darstellen.

    Für interessierte, die BNF Gramatik von C++ (HCB = Hyperlinked C++ BNF Grammar)

    Wenn es eine BNF-Grammatik gibt, dann ist C++ aber kontextfrei.



  • Es ist doch alles nur die halbe Wahrheit. Das Problem ist nicht, das C++ Code so schwer zu analysieren ist. Denn schliesslich habe wir ja fast 100% ISO-C++ konforme Compiler, oder nicht?! Die können ja komischerweise unsere angeblich so komplexen Programme parsen und compilieren. Nein, sie schaffen es sogar unsere geistigen C++-Ergüsse noch _zusätzlich_ zu optimieren, wenn wir es mal nicht geschafft haben. Komisch, oder?

    Da tut sich doch dann eine Frage auf: warum soll das technisch nicht möglich sein?

    OK, schwächen wir es ab: warum soll das technisch schwer sein?

    Warum kann z.B. das VisualC++ oder andere C++ IDEs nicht so schöne Features anbieten, wie die ganzen Java IDEs (Eclipse und Netbeans)? Ganz einfach: diese IDEs benutzen die Reflection-Features dieser Sprachen bzw. von den JVMs. Dazu muß erstmal der Code bzw. Klassen durch die JVM gejagd werden (jeder kennt aus Eclipse "Loading Classpath") und dann kann die IDE Informationen anfordern (z.B. in welchem Package liegt Klasse A?).

    Hier liegt bei C++ der Hund begraben: VC++ IDE benutzt _nicht_ den MSVC-Compiler um solche Informationen (die erfolgreich compiliert wurden) anfordern zu können. Es sind zwei verschiedene Komponenten, die Code analysieren und die auch vom VC++ Team weiter entwickelt werden müssen: der Compiler (cl.exe) und der Objektbrowser (der diese *.bcn Datei, oder welches Suffix auch immer, erzeugt).

    Was würde passieren, wenn die IDE den Compiler fragen würde, z.B. in welchem Namespace Klasse A sich befindet? Denn kompiliert hat er das schon mal, wenn nicht, gibts Klasse A auch nicht. Natürlich muß der Compiler "Buch führen" was er alles kompiliert hat. Und genau dieses Feature fehlt dem 20 Jahre alten cl.exe.

    Wer den VC++ Team Blog (ja, den gibts auf MSDN.com!) verfolgt, weiß das das VC++Team genau an der Baustelle arbeitet: den ganzen Compiler neu entwickeln bzw. refactorisieren. Weil dieser Compiler heute nicht mehr richtig wartbar ist (vorallem weil auch noch C++/CLI dazu gekommen ist). Gleichzeitig wird man den Compiler dazu verdonnern, das er die IDE unterstützen kann. Was den Objektbrowser einspart und somit weniger Manpower benötigt.

    Leider werden wir dafür auch im nächsten VC++ (Oras?) keinen C++ Compiler sehen, der viele neue Features bekommen wird. Weil das Team den MSVC renoviert. Aber dafür sollen wir danach eine bessere IDE erhalten, die mit den C#-IDEs (ja, von Java IDEs war natürlich nicht die Rede im Blog) mithalten kann.

    Also, das Problem ist nicht die Sprache, sondern die Tools. Und die Wurzel des "Übels" ist einfach der Compiler. Übrigens, GCC, DMC, Intel Compiler usw. werden das gleiche Problem haben.

    Z.B. hat ein Java-Kollege geglaubt, das Codeersetzung zur Laufzeit eine Java-Domäne ist. Nur, warum sollte das so sein? Es hat doch nichts mit einer Sprache zu tun. Es ist ein Tool-Feature! Als ich ihm das ganze in VC++ vorgeführt habe, hat er sooooo große Augen bekommen. 😃



  • Stimmt Artchi. Und das Beste: Es gab bereits eine IDE die ihre ganzen Informationen ausschliesslich aus dem Output des Compilers gezogen hat.

    Bevor man sein Projekt nicht compiliert hat, war das einzige was die IDE anzubieten hatte die blanken Sourcefiles.

    Der ganze andere Kram (Klassenbrowser, Vererbungsdiagramm, Callreference, etc) kam erst nach dem Build dazu.

    Das gute Stück hiess Visual Age C++ und war von IBM. Leider wurde die Entwicklung der Windows-Version aber schon vor Jahren eingestellt...

    Wenn MS daran arbeitet freue ich mich schon auf die nächste VC-Version.



  • What's wrong with C++? schrieb:

    http://www.relisoft.com/tools/CppCritic.html

    But I was there for a big surprise--before I had the opportunity to say anything, they started the criticism of C++ in the earnest--especially Scott.

    Was regt sich Scottie denn so auf? Der hat schließlich ne Menge Asche mit den Tücken von C++ gemacht bzw. macht immer noch Kohle damit.



  • Artchi schrieb:

    Warum kann z.B. das VisualC++ oder andere C++ IDEs nicht so schöne Features anbieten, wie die ganzen Java IDEs (Eclipse und Netbeans)? Ganz einfach: diese IDEs benutzen die Reflection-Features dieser Sprachen bzw. von den JVMs. Dazu muß erstmal der Code bzw. Klassen durch die JVM gejagd werden (jeder kennt aus Eclipse "Loading Classpath") und dann kann die IDE Informationen anfordern (z.B. in welchem Package liegt Klasse A?).

    ne is dummfug, alle großen IDEs haben einen parser an bord, der nicht nur ASTs baut, aus denen dann die "klassenbrowser" erstellt werden, sondern z.T. auch noch während des tippens den sourcecode auf fehler (logische, und keine syntax oder sonstigen compilerfehler) analysieren. das machen die bestimmt auch über reflection, nä? 👎



  • Artchi schrieb:

    Es ist doch alles nur die halbe Wahrheit. Das Problem ist nicht, das C++ Code so schwer zu analysieren ist. Denn schliesslich habe wir ja fast 100% ISO-C++ konforme Compiler, oder nicht?! Die können ja komischerweise unsere angeblich so komplexen Programme parsen und compilieren. Nein, sie schaffen es sogar unsere geistigen C++-Ergüsse noch _zusätzlich_ zu optimieren, wenn wir es mal nicht geschafft haben. Komisch, oder?

    Da tut sich doch dann eine Frage auf: warum soll das technisch nicht möglich sein?

    OK, schwächen wir es ab: warum soll das technisch schwer sein?

    Warum kann z.B. das VisualC++ oder andere C++ IDEs nicht so schöne Features anbieten, wie die ganzen Java IDEs (Eclipse und Netbeans)? Ganz einfach: diese IDEs benutzen die Reflection-Features dieser Sprachen bzw. von den JVMs. Dazu muß erstmal der Code bzw. Klassen durch die JVM gejagd werden (jeder kennt aus Eclipse "Loading Classpath") und dann kann die IDE Informationen anfordern (z.B. in welchem Package liegt Klasse A?).

    Hier liegt bei C++ der Hund begraben: VC++ IDE benutzt _nicht_ den MSVC-Compiler um solche Informationen (die erfolgreich compiliert wurden) anfordern zu können. Es sind zwei verschiedene Komponenten, die Code analysieren und die auch vom VC++ Team weiter entwickelt werden müssen: der Compiler (cl.exe) und der Objektbrowser (der diese *.bcn Datei, oder welches Suffix auch immer, erzeugt).

    Was würde passieren, wenn die IDE den Compiler fragen würde, z.B. in welchem Namespace Klasse A sich befindet? Denn kompiliert hat er das schon mal, wenn nicht, gibts Klasse A auch nicht. Natürlich muß der Compiler "Buch führen" was er alles kompiliert hat. Und genau dieses Feature fehlt dem 20 Jahre alten cl.exe.

    Wer den VC++ Team Blog (ja, den gibts auf MSDN.com!) verfolgt, weiß das das VC++Team genau an der Baustelle arbeitet: den ganzen Compiler neu entwickeln bzw. refactorisieren. Weil dieser Compiler heute nicht mehr richtig wartbar ist (vorallem weil auch noch C++/CLI dazu gekommen ist). Gleichzeitig wird man den Compiler dazu verdonnern, das er die IDE unterstützen kann. Was den Objektbrowser einspart und somit weniger Manpower benötigt.

    Leider werden wir dafür auch im nächsten VC++ (Oras?) keinen C++ Compiler sehen, der viele neue Features bekommen wird. Weil das Team den MSVC renoviert. Aber dafür sollen wir danach eine bessere IDE erhalten, die mit den C#-IDEs (ja, von Java IDEs war natürlich nicht die Rede im Blog) mithalten kann.

    Also, das Problem ist nicht die Sprache, sondern die Tools. Und die Wurzel des "Übels" ist einfach der Compiler. Übrigens, GCC, DMC, Intel Compiler usw. werden das gleiche Problem haben.

    👍 Das hört sich mal nach einer guten Entwicklung an. Wenn die Compiler mit den IDEs bei C++ so weit sind, dass sie nicht mehr ein:

    gregor@linux:~/Studium/BV-Projekt/stip> make
    (echo "stip.d \"; g++ -M -c stip.cpp -I/home/gregor/vigra/vigra1.4.0/include) > stip.d
    g++ -O -c stip.cpp -I/home/gregor/vigra/vigra1.4.0/include
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx: In
    function void vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<0>) [with SrcIterator1 = vigra::MultiIterator<1, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<1, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<1, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]': /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:898: instantiated fromvoid vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<2, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 1]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:898: instantiated from void vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff\_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 2]' /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:1166: instantiated fromvoid vigra::combineTwoMultiArrays(SrcIterator1, const SrcShape&, SrcAccessor1, SrcIterator2, SrcAccessor2, DestIterator, DestAccessor, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:1179: instantiated from void vigra::combineTwoMultiArrays(const vigra::triple<T1, T2, T3>&, const std::pair<DestIterator, DestAccessor>&, const std::pair<DestIterator, DestAccessor>&, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]' InterestPointDetection.hxx:165: instantiated fromvoid detectHarrisInterestPoints(SrcIterator, const SrcShape&, SrcAccessor, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]'
    InterestPointDetection.hxx:183: instantiated from void detectHarrisInterestPoints(const vigra::triple<T1, T2, T3>&, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]' stip.cpp:185: instantiated from here /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:858: error: passing \const CornerResponseFunctor<3, double>' as `this' argument of ValueType CornerResponseFunctor<N, ValueType>::operator()(ValueType, ValueType) [with int N = 3, ValueType = double]' discards qualifiers /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:898: instantiated fromvoid vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<2, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 1]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:898: instantiated from void vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff\_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 2]' /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:1166: instantiated fromvoid vigra::combineTwoMultiArrays(SrcIterator1, const SrcShape&, SrcAccessor1, SrcIterator2, SrcAccessor2, DestIterator, DestAccessor, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:1179: instantiated from void vigra::combineTwoMultiArrays(const vigra::triple<T1, T2, T3>&, const std::pair<DestIterator, DestAccessor>&, const std::pair<DestIterator, DestAccessor>&, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]' InterestPointDetection.hxx:165: instantiated fromvoid detectHarrisInterestPoints(SrcIterator, const SrcShape&, SrcAccessor, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]'
    InterestPointDetection.hxx:183: instantiated from void detectHarrisInterestPoints(const vigra::triple<T1, T2, T3>&, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]' stip.cpp:185: instantiated from here /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:864: error: passing \const CornerResponseFunctor<3, double>' as `this' argument of ValueType CornerResponseFunctor<N, ValueType>::operator()(ValueType, ValueType) [with int N = 3, ValueType = double]' discards qualifiers /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:898: instantiated fromvoid vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<2, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 1]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:898: instantiated from void vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff\_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 2]' /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:1166: instantiated fromvoid vigra::combineTwoMultiArrays(SrcIterator1, const SrcShape&, SrcAccessor1, SrcIterator2, SrcAccessor2, DestIterator, DestAccessor, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:1179: instantiated from void vigra::combineTwoMultiArrays(const vigra::triple<T1, T2, T3>&, const std::pair<DestIterator, DestAccessor>&, const std::pair<DestIterator, DestAccessor>&, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]' InterestPointDetection.hxx:165: instantiated fromvoid detectHarrisInterestPoints(SrcIterator, const SrcShape&, SrcAccessor, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]'
    InterestPointDetection.hxx:183: instantiated from void detectHarrisInterestPoints(const vigra::triple<T1, T2, T3>&, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]' stip.cpp:185: instantiated from here /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:870: error: passing \const CornerResponseFunctor<3, double>' as `this' argument of ValueType CornerResponseFunctor<N, ValueType>::operator()(ValueType, ValueType) [with int N = 3, ValueType = double]' discards qualifiers /home/gregor/vigra/vigra1.4.0/include/vigra/combineimages.hxx: In function
    void vigra::combineTwoLines(SrcIterator1, SrcIterator1, SrcAccessor1,
    SrcIterator2, SrcAccessor2, DestIterator, DestAccessor, const Functor&)
    [with SrcIterator1 = vigra::MultiIterator<1, double, const double&, const
    double*>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>,
    SrcIterator2 = vigra::MultiIterator<1, double, const double&, const
    double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>,
    DestIterator = vigra::MultiIterator<1, double, double&, double*>,
    DestAccessor = vigra::StandardValueAccessor<double>, Functor =
    CornerResponseFunctor<3, double>]':
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:874: instantiated from void vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<0>) [with SrcIterator1 = vigra::MultiIterator<1, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<1, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<1, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff\_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]' /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:898: instantiated fromvoid vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<2, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<2, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 1]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:898: instantiated from void vigra::combineTwoMultiArraysExpandImpl(SrcIterator1, const SrcShape1&, SrcAccessor1, SrcIterator2, const SrcShape2&, SrcAccessor2, DestIterator, const DestShape&, DestAccessor, const Functor&, vigra::MetaInt<N>) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape1 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape2 = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestShape = vigra::TinyVector<ptrdiff\_t, 3>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>, int N = 2]' /home/gregor/vigra/vigra1.4.0/include/vigra/multi\_pointoperators.hxx:1166: instantiated fromvoid vigra::combineTwoMultiArrays(SrcIterator1, const SrcShape&, SrcAccessor1, SrcIterator2, SrcAccessor2, DestIterator, DestAccessor, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]'
    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:1179: instantiated from void vigra::combineTwoMultiArrays(const vigra::triple<T1, T2, T3>&, const std::pair<DestIterator, DestAccessor>&, const std::pair<DestIterator, DestAccessor>&, const Functor&) [with SrcIterator1 = vigra::MultiIterator<3, double, const double&, const double*>, SrcShape = vigra::TinyVector<ptrdiff\_t, 3>, SrcAccessor1 = vigra::StandardConstValueAccessor<double>, SrcIterator2 = vigra::MultiIterator<3, double, const double&, const double*>, SrcAccessor2 = vigra::StandardConstValueAccessor<double>, DestIterator = vigra::MultiIterator<3, double, double&, double*>, DestAccessor = vigra::StandardValueAccessor<double>, Functor = CornerResponseFunctor<3, double>]' InterestPointDetection.hxx:165: instantiated fromvoid detectHarrisInterestPoints(SrcIterator, const SrcShape&, SrcAccessor, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]'
    InterestPointDetection.hxx:183: instantiated from void detectHarrisInterestPoints(const vigra::triple<T1, T2, T3>&, double, double, double, std::vector<InterestPointType, std::allocator<InterestPointType> >&) [with SrcIterator = vigra::MultiIterator<3, unsigned char, const unsigned char&, const unsigned char*>, SrcShape = vigra::TinyVector<ptrdiff_t, 3>, SrcAccessor = vigra::StandardConstValueAccessor<unsigned char>, InterestPointType = InterestPoint<3>]' stip.cpp:185: instantiated from here /home/gregor/vigra/vigra1.4.0/include/vigra/combineimages.hxx:73: error: passing \const CornerResponseFunctor<3, double>' as `this' argument of `ValueType
    CornerResponseFunctor<N, ValueType>::operator()(ValueType, ValueType) [with
    int N = 3, ValueType = double]' discards qualifiers
    make: *** [stip.o] Fehler 1

    anzeigen, sondern stattdessen die Zeile 144 in der betroffenen Datei markieren und dazu sagen, dass da ein const vergessen wurde, dann wäre man schon ein ganzes Stück weiter. Da würde ich mich dann glatt auch wieder für C++ begeistern können. 🙂 😉



  • C++ ist halt nichts für kleine Kinder 🙄





  • Gregor schrieb:

    ...anzeigen, sondern stattdessen die Zeile 144 in der betroffenen Datei markieren und dazu sagen, dass da ein const vergessen wurde, dann wäre man schon ein ganzes Stück weiter. Da würde ich mich dann glatt auch wieder für C++ begeistern können. 🙂 😉

    Code::Blocks markiert mir eigentlich immer die Zeile, wo der Fehler ist. vielleicht mußte für c++ auch ne IDE benutzen.



  • Also solche Error-Meldungen sind schon extream schlecht. Aber mit MSVC7.1 hat sich das schon sehr gebessert. Template-Fehler werden schon recht verständlicher dem User mitgeteilt. MSVC8 soll es wohlsogar besser sein.

    Die Zeile markieren kann VC++ in dem ich auf die Fehlermeldung einen Doppelklick mache. Fehler und Warnings werden zus. in der Todo-Liste tabellarisch angezeigt, wo ich dann die Errors/Warnings sortieren lassen kann.

    Aber die IDEs sind im Endeffekt tatsächlich noch sehr weit weg von Java-IDEs.



  • volkard schrieb:

    Gregor schrieb:

    ...anzeigen, sondern stattdessen die Zeile 144 in der betroffenen Datei markieren und dazu sagen, dass da ein const vergessen wurde, dann wäre man schon ein ganzes Stück weiter. Da würde ich mich dann glatt auch wieder für C++ begeistern können. 🙂 😉

    Code::Blocks markiert mir eigentlich immer die Zeile, wo der Fehler ist. vielleicht mußte für c++ auch ne IDE benutzen.

    Interessant. Wie ist diese Zeile denn definiert? In der Fehlermeldung da oben taucht die Zeile, in der der Fehler tatsächlich steckt, zumindest an keiner Stelle auf. Woher kriegt die IDE die Zeile, wenn der Compiler sie nicht findet?



  • /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:858: error: passing
    `const CornerResponseFunctor<3, double>' as `this' argument of `ValueType
    CornerResponseFunctor<N, ValueType>::operator()(ValueType, ValueType) [with
    int N = 3, ValueType = double]' discards qualifiers
    

    hier bitte das sagt alles 🙂 - nicht das fehlende const ist für den compiler der fehler, sondern der falsche aufruf. was ja auch stimmt. irgendwie.

    EDIT: das habe ich tatsächlich durch schnelles überfliegen der meldung gefunden



  • Mr. N schrieb:

    /home/gregor/vigra/vigra1.4.0/include/vigra/multi_pointoperators.hxx:858: error: passing
    `const CornerResponseFunctor<3, double>' as `this' argument of `ValueType
    CornerResponseFunctor<N, ValueType>::operator()(ValueType, ValueType) [with
    int N = 3, ValueType = double]' discards qualifiers
    

    hier bitte das sagt alles 🙂 - nicht das fehlende const ist für den compiler der fehler, sondern der falsche aufruf. was ja auch stimmt. irgendwie.

    EDIT: das habe ich tatsächlich durch schnelles überfliegen der meldung gefunden

    Na gratuliere. Dann schickt mich die Fehlermeldung also ganz tief in die von mir genutzte Bibliothek. ...ganz weit vom Fehler weg. 🙂



  • Gregor schrieb:

    Na gratuliere. Dann schickt mich die Fehlermeldung also ganz tief in die von mir genutzte Bibliothek. ...ganz weit vom Fehler weg. 🙂

    Das ist nunmal so mit Callbacks. Der Compiler denkt: "Die Library verwendet deinen Code falsch." - dass es andersrum ist, KANN er garnicht ahnen.

    Ja, er könnte bessere Meldungen bringen. Das muss halt jemand implementieren. Und da stecken Sun, MS und IBM bei Java und .NET halt mehr Geld rein als z.B. die GCC-Entwickler.



  • Gregor schrieb:

    Wie ist diese Zeile denn definiert?

    durch "error:".
    eigentlich durch "([ \tA-Za-z0-9_:+/\.-]+):([0-9]+):[ \t](.*)", nachdem ein paar andere regexps warnungen und so schon gefunden haben.

    In der Fehlermeldung da oben taucht die Zeile, in der der Fehler tatsächlich steckt, zumindest an keiner Stelle auf. Woher kriegt die IDE die Zeile, wenn der Compiler sie nicht findet?

    sondern stattdessen die Zeile 144 in der betroffenen Datei markieren und dazu sagen, dass da ein const vergessen wurde

    du beklagst dich doch auch nicht bei nem tippfehler in der deklaration, daß die ide gefälligst deine gedanken lesen soll und statt beinm aufruf bei der deklaration den cursor hinsetzen soll. und mal ernsthaft, wie stellste dir das bei const vor? bei jedem aufruf einer stl-funktion soll er in den stl-code springen, weil er annimmt, der aufrufer ist nicht dran schuld, sondern die benutzen klassen haben schlechte deklarationen? oder manchmal andersrum, weil ich der stl was untergejubelt hab. oder speichern wir zu jeder datei den ersteller ab und machen nen intelligenzvergleich und der laut datenbank dümmere kriegt immer den cursor? wenn wir einfach nur davon ausgehen, daß der c++-programmierer ein krasses anfängerbuch und effektiv c++ programmieren gelesen hat, ist ihm mit einer ide, die ihn einfach auf die fehlerzeile schmeißt, viel mehr gedient, als mit einer hypothetischen vermuteter-fehler-anzeige. sollte so viel kraft über sein, ein system zu bauen, das aus fehlerhaftem code korrekten code baut, ist es für eine noch zu erfindende unscharfe programmiersprache sprache benutzen. bei c++-IDEs ist sowas fehl am platze. man will sich ja auch an das immer gleiche verhalten des compilers gewöhnen, so wie man sich an sein auto gewöhnt, und nach kurzer zeit erfasst man solche fehler ohne genauer hinzusehen.
    aber ich weiß schon, in "Rund um die Programmierung" ist es zur zeit modern, aus java-sicht mit möglichst wenig fachwissen an c++ rumzunörgeln.

    zum topic: ja, c++ ist schwer zu parsen.



  • @volkard: Schon gut. 😉 Ich habe hier ja nur ne Frage gestellt und ich hatte den Fehler, als er vor ein paar Tagen auftrat, ja auch gefunden. Aber es ärgert einen halt als Nicht-C++-Profi, dass man bei einem Fehler gleich mit so einer riesigen Fehlermeldung erschlagen wird. Warum kann so eine Fehlermeldung nicht etwas lesbarer sein? ...ok, für Dich ist sicherlich nach 2 Sekunden klar, was da schief gelaufen ist. Für mich zugegebenermaßen nicht. 🙄

    MrN hat im Chat angedeutet, dass mit dem neuen Standard "Concepts" kommen sollen, die bei so einer Fehlermeldung wohl etwas bringen. Ich bin da also ganz optimistisch, dass soetwas in Zukunft lesbarer werden wird. Hoffentlich kommt der neue Standard bald.

    BTW: Die Java-IDEs machen tatsächlich immer ein paar Vorschläge zur Korrektur von Fehlermeldungen, die natürlich auch mit einbeziehen, was der Nutzer falsch gemacht haben könnte. Da nutzt man Fehlermeldungen nicht nur, um Fehler zu beheben, sondern auch, um mit ein paar Klicks bestimmte Methoden zu deklarieren, also zur Generierung von Code. ...ein durchaus praktisches Feature der IDEs. Einen, zu dem hier geposteten Fehler, äquivalenten Fehler gibt es zwar so bei Java nicht, aber ich sehe keinen Grund, warum eine IDE nicht den passenden Vorschlag zur Korrektur dieses Fehlers anbieten sollte.



  • Gregor schrieb:

    ...ok, für Dich ist sicherlich nach 2 Sekunden klar, was da schief gelaufen ist. Für mich zugegebenermaßen nicht. 🙄

    das "discards qualifiers" sagt "du hast nen fehler mit const" gemacht. zusammen mit der angewohnheit, oft zu compilieren, weiß man ja, was man zuletzt gemacht hat und 2 sekunden wären verdammt lang. natürlich ne IDE vorausgesetzt, die den fehlertext des ersten fehlers immer an die gleiche stelle auf dem bildschirm schreibt und die entsprechende codezeile markiert.

    MrN hat im Chat angedeutet, dass mit dem neuen Standard "Concepts" kommen sollen, die bei so einer Fehlermeldung wohl etwas bringen. Ich bin da also ganz optimistisch, dass soetwas in Zukunft lesbarer werden wird. Hoffentlich kommt der neue Standard bald.

    ja, wird zeit.

    BTW: Die Java-IDEs machen tatsächlich immer ein paar Vorschläge zur Korrektur von Fehlermeldungen, die natürlich auch mit einbeziehen, was der Nutzer falsch gemacht haben könnte. Da nutzt man Fehlermeldungen nicht nur, um Fehler zu beheben, sondern auch, um mit ein paar Klicks bestimmte Methoden zu deklarieren, also zur Generierung von Code.

    ja, daran könnte ich mich gewöhnen. dem würde ich gleich beibringen, daß ein fehler in einer zeile, wo retrun vorkommt, vermutlich behoben werden kann, wenn man stattdessen return schreibt.


Anmelden zum Antworten