Forum: Mikrocontroller und Digitale Elektronik expected unqualified-id before '?' token


von Ramon H. (mrrayman)


Lesenswert?

Irgendwas ist mit diesen Code nicht in Ordnung. Wenn ich die 
Klassendefinition auskommentiere wird das Programm kompliert, sodass 
hier der Fehler drin strecken muss.

Fehler
Error:       expected unqualified-id before '?' token
Line :       8

Vielen Danke für die Hilfe und ein frohes Weihnachtsfest

_____________________________________________________________________

#include "confic.h"
#include "function.c"
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/io.h>
#include "function.h"

class CFlag //Hier ist Line 8
{
  private:
    char Flag;

  public:
    CFlag()
    {
      Flag = 0;
    }

    void changeFlag()
    {
      if (Flag == 0)
      {
        Flag = 1;
      }
      else
      {
        Flag = 0;
      }
    }

    char GetFlag()
    {
      return Flag;
    }
};

von Peter II (Gast)


Lesenswert?

was steht denn in function.h?

von Rolf M. (rmagnus)


Lesenswert?

Auf den ersten Blick würde ich sagen, dass irgeneine der eingebundenen 
Dateien ein Makro namens "class" oder "CFlag" definiert. Geht der Fehler 
weg, wenn du der Klasse einen anderen Namen gibst?

von Ramon H. (mrrayman)


Lesenswert?

Ich habe das Programm einmal soweit reduziert, dass ich die function.h 
auskommentieren konnte. In ihr stehen nur die Prototypen vom Methoden 
(also ich meine sowas wie    void methode ();     ) aus der function.c

Ja, ich habe die Klasse mal Flagabcde genannt. Es tritt der gleiche 
Fehler auf.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Ramon H. schrieb:
> sodass
> hier der Fehler drin strecken muss.
Muss er nicht.

Ramon H. schrieb:
> #include "function.c"
sowas macht man nicht.

Ramon H. schrieb:
> char Flag;
Nimm alles aber kein char. Wenn es eh nur 2 Werte annehmen kann ist bool 
passender.

Ramon H. schrieb:
> void changeFlag()
>     {
>       if (Flag == 0)
>       {
>         Flag = 1;
>       }
>       else
>       {
>         Flag = 0;
>       }
>     }
Wie waers mit
1
void changeFlag() {
2
    Flag = !Flag;
3
}

Ramon H. schrieb:
> Ja, ich habe die Klasse mal Flagabcde genannt. Es tritt der gleiche
> Fehler auf.
Zeig den GANZEN Code, sonst kann dir keiner helfen.

Benutzt du auch den richtigen Compiler, also avr-g++ und nicht avr-gcc?

von Markus F. (mfro)


Lesenswert?

Der Fehler ist da, wo das Fragezeichen ist. Nachdem im gezeigten Code 
keins zu finden ist, ist er da auch nicht.

von A. S. (Gast)


Lesenswert?

Poste bitte die ganze Fehlermeldung.

Und ggf. den Compiler-Aufruf

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ramon H. schrieb:
> In ihr stehen nur die Prototypen vom Methoden (also ich meine sowas wie
> void methode ();     ) aus der function.c

C kennt keine Klassen, und folglich auch keine Memberfunktionen 
("Methoden").

Du willst einen C++-Compiler verwenden, also muss Dein Sourcefile *.cpp 
heißen.

von Ramon H. (mrrayman)


Lesenswert?

Erst mal vielen Dank für die ganzen Verbesserungen und Hinweise. Wenn 
ich nächste mal eine Frage habe poste ich sofort den ganzen Code.

Also ich heute den Rechner neu gestartet habe, konnte ich sofort den 
Fehler finden. Es stand wirklich ein Fragezeichen vor 'class'.

?class CFlag //Hier ist Line 8

Kann man irgendwie Zeichen unsichtbar machen oder irgendwas mit den 
speichern falsch machen?

Ich habe eigentlich den Code direkt hier hin kopiert und habe selbst 
auch mehrfach über den Code und besonder diese Stelle drüber gesehen. 
Verrückt...

Kaj G. schrieb:
> Ramon H. schrieb:
>> #include "function.c"
> sowas macht man nicht.

Was wäre denn die Alternative? Einfach alles in der Main.cpp stehen 
lassen?

von Rolf M. (rmagnus)


Lesenswert?

Ramon H. schrieb:
> ?class CFlag //Hier ist Line 8
>
> Kann man irgendwie Zeichen unsichtbar machen oder irgendwas mit den
> speichern falsch machen?

Vielleicht die Datei in einer Editor-Instanz abgespeichert, aber noch 
eine alte Version in einer anderen Instanz offen gehabt? Wenn du einen 
schlechten Editor hast, der solche Änderungen der Datei nicht 
mitbekommt, könnte sowas passieren.

Ramon H. schrieb:
> Kaj G. schrieb:
>> Ramon H. schrieb:
>>> #include "function.c"
>> sowas macht man nicht.
>
> Was wäre denn die Alternative? Einfach alles in der Main.cpp stehen
> lassen?

Nein. Du lässt sie vom Compiler separat bauen und linkst dann die beiden 
zusammen. Was meinst du, wie richtig große Programme aus hunderten bis 
tausenden von C-Files gebaut werden? Alle per Include in der main-Datei 
eingebunden?

von ich file (Gast)


Lesenswert?

> Du willst einen C++-Compiler verwenden, also muss Dein Sourcefile *.cpp
> heißen.

Der Wink zum passenden Compiler passt.

Jedoch sind Namen Schall und Rauch: nur BertriebsUNsysteme setzen auf 
die letzten 4 Buchstaben des Dateinamens und bestehen darauf dass der 
4rtletzte ein '.' sein muss.

Ordnung zu halten hilft alleweil.

von Rolf M. (rmagnus)


Lesenswert?

ich file schrieb:
>> Du willst einen C++-Compiler verwenden, also muss Dein Sourcefile *.cpp
>> heißen.
>
> Der Wink zum passenden Compiler passt.
>
> Jedoch sind Namen Schall und Rauch: nur BertriebsUNsysteme setzen auf
> die letzten 4 Buchstaben des Dateinamens und bestehen darauf dass der
> 4rtletzte ein '.' sein muss.

Nein, Compiler und viele Makefiles tun das auch, wenn man ihnen nicht 
explizit sagt, als was sie die Datei einlesen sollen. Eine zuverlässige 
Unterscheidung zwischen C und C++ basierend auf dem Inhalt dürfte auch 
recht komplex werden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

ich file schrieb:
> Jedoch sind Namen Schall und Rauch

Es gibt Genies, die die Fähigkeit der von ihnen verwendeten 
Betriebssysteme nutzen, zwischen *.c und *.C zu unterscheiden, und das 
eine als C-, das andere als C++-Quelltext interpretieren.
Die dahintersteckende Genialität verpufft aber recht schnell, wenn man 
über den Tellerrand des eigenen Betriebssystems hinausblickt, und das 
"Genie" steht in einer Reihe mit den Strebern, die das Akronym "BASIC" 
auflösen können und sich dabei sehr wichtig vorkommen.

In der Regel mendelt sich sowas nach ein paar Monaten Erwachsenwerden 
aus.

von ich file (Gast)


Lesenswert?

> Nein, Compiler und viele Makefiles tun das auch, wenn man ihnen nicht
> explizit sagt, als was sie die Datei einlesen sollen.
"Explicit is better than implicit" spätestens wenn man ein hartnäckiger 
Problemfall zu entwanzen hat.
Anderseits gibt es gar Künstler in der Sparte, die bekommen ihr 
C-Projekt mit einem Aufruf "make" übersetzt, ohne dass ein Makefile da 
liegt...

> Eine zuverlässige
> Unterscheidung zwischen C und C++ basierend auf dem Inhalt dürfte auch
> recht komplex werden.
Ja stell dir vor: ich komme hie und da nicht umhin C und C++ Quellcode 
in die selbe Datei hineinzuschreiben. Wie bekomme ich nun 2 Endungen an 
den Dateinamen?

von Peter II (Gast)


Lesenswert?

ich file schrieb:
> Ja stell dir vor: ich komme hie und da nicht umhin C und C++ Quellcode
> in die selbe Datei hineinzuschreiben. Wie bekomme ich nun 2 Endungen an
> den Dateinamen?

und wie übersetzt du die Datei? Passt du jedes mal das Makefile an, ob 
es mal als C++ oder C zu übersetzen. Oder denkst du nur das du C 
schreibt, aber immer als C++ übersetzt?

von ich file (Gast)


Lesenswert?

Rufus Τ. Firefly (rufus) ( Moderator ) schrieb:

>> Jedoch sind Namen Schall und Rauch
:
> Strebern, die das Akronym "BASIC"
> auflösen können und sich dabei sehr wichtig vorkommen.

hmm, da war doch was...
B ewahre: A dminhelfer(aka: Moderatoren)- S euche I nfiziert die 
C omputer!

von ich file (Gast)


Lesenswert?

> und wie übersetzt du die Datei? Passt du jedes mal das Makefile an, ob
> es mal als C++ oder C zu übersetzen. Oder denkst du nur das du C
> schreibt, aber immer als C++ übersetzt?

Jaja, mit dem Thinkfile anstelle des Makefiles. Die kommen mit dem 
Patch zu Brain-2.0-15a.

Explicit rules, anyone?

Ausserdem kann make ja NUR UND AUSSCHLIESSLICH Compilers aufrufen...

von ich file (Gast)


Lesenswert?

DISCLAIMER
ich bin in keinster Weise mit dem hier berühmten Paul in Verbindung, 
ausser dass ich seine Auftritte in diesem Kleintheater lese und meist 
erfrischend finde.
Vielleicht bin ich aber nach ihm das zweite Opfer psychischer 
Beschädigung wegen dem frequentieren dieses Forums - und dies gar 
ohne Anmeldung.
Oder Imitator.
Oder Fehler in der Matrix.

Paul: blau oder rot heute?

;-)

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Ramon H. schrieb:
> Kaj G. schrieb:
>> Ramon H. schrieb:
>>> #include "function.c"
>> sowas macht man nicht.
>
> Was wäre denn die Alternative? Einfach alles in der Main.cpp stehen
> lassen?
1
// Datei: foo.h
2
void do_what_have_to_be_done(void);
1
// Datei: foo.c
2
#include "foo.h"
3
4
void do_what_have_to_be_done(void) {
5
    do_stuff();
6
}
1
// Datei: main.c
2
#include "foo.h"
3
4
int main(void) {
5
    do_what_have_to_be_done();
6
    return 0;
7
}

Compileraufruf:
1
gcc -I./ -o main main.c foo.c
Der Aufruf stellt nur ein Beispiel dar, ebenso der gcc. Geht genauso mit 
dem g++ und analog dazu auch mit cpp-Dateien.

Das kann man auch ueber ein belibiges Buildsystem machen lassen:
make, cmake, Scons, what ever.

von Rolf M. (rmagnus)


Lesenswert?

ich file schrieb:
>> Nein, Compiler und viele Makefiles tun das auch, wenn man ihnen nicht
>> explizit sagt, als was sie die Datei einlesen sollen.
> "Explicit is better than implicit"

Na dann ist ja alles prima. Es geht ja kaum expliziter, als schon in den 
Namen zu schreiben, um was es sich handelt.

> spätestens wenn man ein hartnäckiger Problemfall zu entwanzen hat.

Hmm, also wenn für jemanden eine simple Unterscheidung zwischen zwei 
Endungen von Dateinamen schon ein "hartnäckiger Problemfall" ist, dann 
wäre vielleicht ein anderes Hobby als ausgerechnet C und C++ angebracht. 
Briefmarkensammeln soll sehr entspannend sein.

> Anderseits gibt es gar Künstler in der Sparte, die bekommen ihr
> C-Projekt mit einem Aufruf "make" übersetzt, ohne dass ein Makefile da
> liegt...

Für Einfachstprogramme, um mal kurz was zu testen, mache ich das 
manchmal auch.

>> Eine zuverlässige
>> Unterscheidung zwischen C und C++ basierend auf dem Inhalt dürfte auch
>> recht komplex werden.
> Ja stell dir vor: ich komme hie und da nicht umhin C und C++ Quellcode
> in die selbe Datei hineinzuschreiben.

Wozu um alles in der Welt soll das denn gut sein? Und wie erkennt dein 
Betriebssystem, von dem du oben sprichst, welcher Teil nun C und welcher 
C++ ist, und warum können diese verschiedenen Quellcodes nicht in 
getrennten Dateien stehen?

ich file schrieb:
> Ausserdem kann make ja NUR UND AUSSCHLIESSLICH Compilers aufrufen...

Wie soll man das verstehen? Du schreibst Quellcode-Dateien, wo in einem 
Quellcode mehrere Sprachen miteinander vermischt werden und übergibst 
sie dann nicht an einen Compiler sondern an irgendwas anderes 
geheimnisvolles? Und dadurch bist du auf das Problem gestoßen, dass dein 
- doch sehr ungewöhnlicher - Fall nicht damit harmoniert, die Sprache 
über den Dateinamen zu erkennen?
Du bist lustig...

von ich file (Gast)


Lesenswert?

Vermischen wir 2 Dinge nicht.

Nur weil eine gewisse Klasse BetriebsUNsysteme so sehr an Dateiendungen 
hängt, müssen Benutzer -insbesondere wenn sie Programmieren- sich diese 
Denke nicht indoktrinieren lassen.

-----

Nun stell dir vor es gibt (SW-)Aufgaben ausserhalb uC.net, da geht es um 
verteilte Systeme und da sind über die Jahre diverse 
uC/CPU-Architekturen und sogar Programmiersprachen (nebst C/C++ auch M2, 
Java, asm) zusammengekommen.
(In 2 Jahrzehnte gut ein Dutzend "Teile", embedded Einschubmodule u. 
Workstationanwendungen, z.T. 3 Generationen davon. Natürlich nicht alle 
ab Tag 1 dabei, zu Beginn waren's ca. 4)

Da tauschen Module also Daten untereinander aus (über Schnittstellen) 
und die wollen die selben structs decodieren und schreiben können. Mit 
der Zeit wo das Systemprodukt so vor sich hin exisitiert und evolviert, 
kommen da immer mal wieder Verbesserungen und Ergänzungen hinzu: 
manchmal bloß Datendefinitionen, manchmal Librarycode für das hantieren 
mit solchen Daten.

Weil es sich nun nicht gehört solche "Evolution" in jeder Plattform 
einzeln Händisch einzupflegen (Zeitaufwand, Fehlerquelle, ...) ist das 
zentral "Single Source" gehalten und versioniert.
Spricht nun ein Beteiligter von "Datenschema Version xyz" wissen alle 
-ALLE!- anderen Beteilgten wovon die Rede ist und verbindlich ist dann 
genau EINE Definition, für alle Personen und alle Toolchains.

Geht es nur um C/C++ liegen (leider) ein paar Präprozessor 
Macrohantierungen drin, um im selben Sourcefile ein paar wenige Dinge 
mzustellen sodass sich der Code als C oder als C++ anfühlt.

Für andere Sprachen reicht Präprozessor natürlich nicht, da kommt ein 
umformender Codegenerator zum Zuge. Dieser wird -trara!- auch aus 
Makefiles aufgerufen: mal entsteht Java, mal M2, mal direkt 
Objektcodeaus dem selben Quellfile.
Generische (implizite) make Regeln kommen da manchmal nicht gut, also 
explizite Regeln.

Nein, wegen eines neuen Typs oder einer neuen Generation eines Moduls 
wird nicht die ganze bewährte Codebasis umgepflügt. Das Neue darf mit 
aktuellen state or the art Techniken gemacht werden, das bestehende 
muss deswegen nicht in die Tonne sondern wird in bestehender 
Arbeitstechnik erweitert.

Rückblickend hätte man damals vielleicht besser... ${IRGENDWAS}

Sicher. War aber vllt. nicht erhältlich, nicht reif, oder den Damaligen 
nicht bekannt.

Nicht jede Firma kann der Langzeiterfolg eines (komplexen) Produktes 
exakt planen, man kann die bisherigen Kunden nur bestmöglichst bedienen.
 Also muss für die folglich gefragten Erweiterungen (wg. neuen Kunden) 
die Flexibilität in der  Arbeitstechnik maximal genutzt werden - SW hat 
da mehr Spielraum als HW.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.