2016-09-22 3 views
1

Ich arbeite an einer großen Codebase, die Apache Xerces verwendet. Ich baue den Code mit clang ++ und es gab einen Fehler.Fehler mit beiden include und forward-Deklaration

In einer speziellen H-Datei a.h, Header für a.cpp gibt es sowohl vorwärts Deklaration und gibt die Header-Datei der Klasse wie folgt Attribute -

#include <xercesc/sax2/Attributes.hpp> 

und

namespace XERCES_CPP_NAMESPACE{ 
    class Attributes; 
} 

Die Datei xercesc/sax2/Attributes.hpp hat den Code

XERCES_CPP_NAMESPACE_BEGIN 
...<some code>... 
class SAX2_EXPORT Attributes { 
    ...<some code>... 
} 
...<some code>... 
XERCES_CPP_NAMESPACE_END 

Der Fehler hier, während Sie den Code mit Klirren Aufbau ist

a.cpp:45:39: error: member access into incomplete type 'const obixercesc_2_8::Attributes' 
a.h:20:10: forward declaration of 'obixercesc_2_8::obixercesc_2_8::Attributes' 
    class Attributes; 

Dies ist die entsprechende Zeile aus a.cpp ist, die den Fehler

void f(const XERCES_CPP_NAMESPACE::Attributes& attrs) { 
/* this line ---> */ const XMLCh * pAppName = attrs.getValue(X("appName")); 

wirft Aber das kompiliert völlig in Ordnung, wenn ich die Vorwärts-Erklärung auf Kommentar und schließe nur den Attribute-Header in ah ein Der Code wird auch erstellt, wenn ich g ++ anstelle von clang ++ verwende.

Ich verstehe nicht, einige Dinge -

1) Warum ist es nicht mit Klirren Aufbau ++, wenn beide sind Forward-Deklaration und beinhalten?

2) Warum zeigt der Fehler auf obixercesc_2_8 :: Attribute, aber nicht auf XERCES_CPP_NAMESPACE :: Attribute, der tatsächliche Namespace der Klasse Attribute?

3) Warum wird der Code mit g ++ kompiliert?

Antwort

1

Dies ist eher eine Hypothese als eine Lösung, aber wie auch immer, hier ist ein Gedanke.

Aus irgendeinem Grunde sind Sie Attributes fälschlicherweise in verschachtelter Namespace voraus erklärt obixercesc_2_8::obixercesc_2_8, und wenn Sie obixercesc_2_8::Attributes Bezug sind, wählt Clang Ihre Forward-Deklaration über die Umsetzung von Xerces, weil sie nicht im gleichen Namensraum ist (vielleicht wegen eines using namespace Aussage?). Aus ihrer Sicht haben Sie zwei Deklarationen von Attributes, eine in obixercesc_2_8 und eine in obixercesc_2_8::obixercesc_2_8. XERCES_CPP_NAMESPACE scheint ein Makro zu sein, das auf obixercesc_2_8 erweitert wird.

+0

Das war das Problem. Vielen Dank. – Sashank