Forum: Compiler & IDEs Anfängerfrage Klassen / Makefile


von Tilo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Ich arbeite seit einer Weiler mit gnuarm und habe schon einige
Programme in C hinbekommen. Nun will ich meinen Uart Code für
einen ADUC7000 zusammenfassen. Ich dachte dabei an eine "Klasse".

Nun gibt es in standard-C keine Klassen, nur Strukturen. Mit Strukturen
scheint das ganze aber etwas umstädlich zu sein, da in der Struktur 
keine
Funktion deklariert werden kann, zumindest scheint es bei mir so.

struct test {
  int function1(int i);
};

Hier bleibt der Compiler hängen. Fehlermeldung: Es wurde eine Funktion 
definiert.

Als nächstes habe ich mir überlegt, in der Struktur Pointer zu 
definieren,
die auf die entsprechenden Funktionen zeigen. Das scheint aber sehr 
umständlich zu sein.

Daher war meine Idee, auf C++ umzuschwenken, da dort Klassen definiert 
sind.
Da C++ eine Obermenge von C ist, sollte der restliche C-Code laufen.
Mein Problem ist, dass ich keine ahnung habe, wo ich meine Makefile 
anpassen
muss, damit der Code als C++ Code und nciht als C-Code interpretiert 
wird.

Kann mir einer von euch dabei helfen?

anbei meine Makefile.

Vielen Dank,

Tilo

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du benutzt einfach einen der automatisch erkannten Dateinamenssuffixe
für C++:

       file.cc
       file.cp
       file.cxx
       file.cpp
       file.CPP
       file.c++
       file.C
           C++ source code which must be preprocessed.  Note that in
           .cxx, the last two letters must both be literally x.
           Likewise, .C refers to a literal capital C.

Die Aussage:

> Da C++ eine Obermenge von C ist, ...

ist zwar nicht wirklich korrekt, aber kann eine brauchbare Näherung
sein.

von Rolf Magnus (Gast)


Lesenswert?

> Nun gibt es in standard-C keine Klassen, nur Strukturen. Mit Strukturen
> scheint das ganze aber etwas umstädlich zu sein, da in der Struktur
> keine Funktion deklariert werden kann, zumindest scheint es bei mir so.

Kann man schon, aber halt nicht in C.

> Als nächstes habe ich mir überlegt, in der Struktur Pointer zu
> definieren, die auf die entsprechenden Funktionen zeigen. Das scheint
> aber sehr umständlich zu sein.

Es kostet natürlich auch Platz, da jedes Objekt pro Funktion einen 
Zeiger enthält. Außerdem müssen diese initialisiert werden.

> Da C++ eine Obermenge von C ist, sollte der restliche C-Code laufen.

Das stimmt nicht so ganz. Es gibt durchaus Unterschiede, aber eine 
Anpassung sollte je nach Code mit relativ wenig Aufwand möglich sein.

> Mein Problem ist, dass ich keine ahnung habe, wo ich meine Makefile
> anpassen muss, damit der Code als C++ Code und nciht als C-Code
> interpretiert wird.

So wie du CC und CFLAGS definiert hast, mußt du jetzt auch CXX und 
CXXFLAGS definieren. CXX ist dann arm-elf-g++. Die .c-Dateien benennst 
du um nach *.cpp oder eine andere übliche C++-Endung. Dann mußt du eine 
Regel zur Übersetzung der Dateien definieren. Statt wie in deinem Fall 
für jede Datei eine eigene Regel zu definieren, wäre es sowieso noch 
sinnvoll, eine generische Regel zu verfassen, etwa so:
1
%o: %.cpp
2
        @ echo " compiling $@"
3
        $(CXX) $(CXXFLAGS) $< -o $@

von Tilo (Gast)


Lesenswert?

Vielen Dank für eure Tips. Ihr habt mir sehr weitergeholfen.
Ich habe meine main.c in main.cpp umbenannt und in der Makefile
die entsprechenden Änderungen gemacht.
Die Umstellung auf C++ scheint funktioniert zu haben.

Leider funktioniert dafür jetzt etwas anderes nicht mehr.
Ich habe meinen uart-Code in eine Header File gepackt:
uart.h und uart.c. Der Code ist in C geschrieben. Ich habe mich dabei
an http://de.wikibooks.org/wiki/C-Programmierung:_Eigene_Header
orientiert. Ich habe die uart.o als Object angegeben und sie wurde
in reinem C als uart.o erzeugt und genutzt.

Die Datei uart.o wird immer noch erzeugt. Leider kann die Funktion nicht
mehr genutzt werden:

#include uart.h

int main (void)  {
  IRQ = IRQ_Function;  // Weise IRQ Funkion zu
  InitUart(115200); // Starte Uart
}

#####
/Users/tilolutz/Documents/workspace/Uart_Demo/main.cpp:20: undefined 
reference to `InitUart(int)'



Kann es sein, dass C und C++ Code nicht gemischt werden kann?



@Ralf: Das mit der Makefileänderung und g++ schau ich mir noch genauer 
an.
arm-elf-gcc scheint den C++ Code jedenfalls zu erkennen:
arm-elf-gcc -I./ -c -fno-common -mcpu=arm7tdmi -O0 -g -std=gnu99 
main.cpp
cc1plus: warning: command line option "-std=gnu99" is valid for C/ObjC 
but not for C++


Bis dann, Tilo

von Sven W. (woehlb)


Lesenswert?

Ich kenne den gcc nicht gut genug, um eine spezifische Aussage zu diesem 
Compiler zu treffen. Im Allgemeinen erzeugen aber C++ Programme einen 
größeren Overhead als vergleichbare C Programme. Das kann auf einem 
kleinen Mikroconroller hinsichtlich des vorhandenen Programmspeichers 
entscheidend sein.

Wenn Du bei C bleibst könntest Du ja wie folgt Deinen Code 
strukturieren. Willst Du z.B. eine Klasse UART schreiben, schreibe keine 
C++ Klasse UART, sondern erstelle die Datei UART.c die dann für die 
Klasse steht, und erstelle in dieser Datei ganz normale C-Funktionen, 
deren Namen für die Methoden dieser "Klasse" stehen. "Klassen interne" 
Variablen werden in UART.c als globale Variblen und  mit dem 
Schlüsselwort "static" vereinbart, beschränkt das Zugriffsrecht auf Code 
in dieser Datei.

So erhälst du einen sinnvoll strukturierten C-Code ohne größeren 
Overhead. Als normales C-Programm stehen natürlich die 
Zugriffbeschränkungen(public, private o. protected) nicht zur Verfügung. 
Ableiten von Klassen ist natürlich auch nicht möglich, es ist dann eben 
ein ganz normales C-Programm, dessen Quellcode lediglich nach dem 
Vorbild von C++ strukturiert ist.

Tschau Sven!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Tilo Lutz wrote:

> Kann es sein, dass C und C++ Code nicht gemischt werden kann?

Doch, aber du musst die Funktionen
1
extern "C" ...

deklarieren.  Damit das nur bei C++ passiert, kannst du den
vordefinierten Makro __cplusplus testen:
1
#if defined(__cplusplus)
2
extern "C" {
3
#endif
4
5
int foo(void);
6
7
void bar(char *);
8
9
#if defined(__cplusplus)
10
}
11
#endif

Selbstverfreilich muss die C-Datei dann auf .c enden und so compiliert
worden sein, erst der Linker bringt das alles zusammen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven Woehlbier wrote:

> Ich kenne den gcc nicht gut genug, um eine spezifische Aussage zu diesem
> Compiler zu treffen. Im Allgemeinen erzeugen aber C++ Programme einen
> größeren Overhead als vergleichbare C Programme.

Im Allgemeinen sind allgemeine Aussagen Quatsch.

Man kann natürlich mit C++ mehr Overhead verursachen, aber man muss es
nicht.  Es sollte klar sein, dass "late binding" Overhead kostet, aber
das würde es auch dann, wenn man ein vergleichbares Modell in C
zusammenbauen möchte.  Es ist dort eben nur offensichtlicher.

von Rolf Magnus (Gast)


Lesenswert?

>> Im Allgemeinen erzeugen aber C++ Programme einen
>> größeren Overhead als vergleichbare C Programme.
>
> Im Allgemeinen sind allgemeine Aussagen Quatsch.

Full Ack.

> Man kann natürlich mit C++ mehr Overhead verursachen, aber man muss es
> nicht.

Ich habe für den AVR durchaus auch schon C++-Code geschrieben, der 
effizienter war als entsprechender C-Code. Wenn man weiß, was der 
Compiler daraus macht, kann man durchaus C++-Features nutzen, ohne daß 
es mehr kostet als reiner C-Code. Manche Features bringen zwar einen 
Overhead, aber den müßte man bei entsprechender Umsetzung in C auch 
zahlen. Nur muß man es in C eben umständlicher schreiben.

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.