Forum: Compiler & IDEs avr-g++ Klasse, programm zu klein


von Marcel (Gast)


Lesenswert?

Hallo,

ich möchte gerne eine Klasse schreiben, bzw. bereits getan.

Die Klasse (zum Ansteuern einzellner oder mehrerer LCDs) erscheint mir 
sehr korrekt, es gibt keine Fehler beim Kompillieren und der Code hat 
als C Variante (also ohne Klasse) funktioniert.

Das Problem ist: nach Erstellung des Programms ist die .hex Datei für 
den Programmspeicher nur etwa 189 Bytes groß und das ist definitiv zu 
wenig.

Ich hab's probiert und das "Programm" läuft nicht.


Ich benutze idR Makefiles, würde aber auch die Kommandozeile benutzen, 
würde ich denn die korrekten Optionen für meinen Fall wissen.


Hier mal das Makefile (von Avr Studio):
1
###############################################################################
2
# Makefile for the project lcd-class
3
###############################################################################
4
5
## General Flags
6
PROJECT = lcd-class
7
MCU = atmega8
8
TARGET = lcd-class.elf
9
CC = avr-gcc
10
11
CPP = avr-g++
12
13
## Options common to compile, link and assembly rules
14
COMMON = -mmcu=$(MCU)
15
16
## Compile options common for all C compilation units.
17
CFLAGS = $(COMMON)
18
CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
19
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d 
20
21
## Assembly specific flags
22
ASMFLAGS = $(COMMON)
23
ASMFLAGS += $(CFLAGS)
24
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
25
26
## Linker flags
27
LDFLAGS = $(COMMON)
28
LDFLAGS +=  -Wl,-Map=lcd-class.map
29
30
31
## Intel Hex file production flags
32
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
33
34
HEX_EEPROM_FLAGS = -j .eeprom
35
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
36
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
37
38
39
## Objects that must be built in order to link
40
OBJECTS = lcd-class.o 
41
42
## Objects explicitly added by the user
43
LINKONLYOBJECTS = 
44
45
## Build
46
all: $(TARGET) lcd-class.hex lcd-class.eep lcd-class.lss size
47
48
## Compile
49
lcd-class.o: ../lcd-class.cpp
50
  $(CPP) $(INCLUDES) $(CFLAGS) -c  $<
51
52
##Link
53
$(TARGET): $(OBJECTS)
54
   $(CPP) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
55
56
%.hex: $(TARGET)
57
  avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@
58
59
%.eep: $(TARGET)
60
  -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
61
62
%.lss: $(TARGET)
63
  avr-objdump -h -S $< > $@
64
65
size: ${TARGET}
66
  @echo
67
  @avr-size -C --mcu=${MCU} ${TARGET}
68
69
## Clean target
70
.PHONY: clean
71
clean:
72
  -rm -rf $(OBJECTS) lcd-class.elf dep/* lcd-class.hex lcd-class.eep lcd-class.lss lcd-class.map
73
74
75
## Other dependencies
76
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)


Das ist jetzt die Standard kompilliermethode für C Programme, ich weiß 
nicht ob man bei C++ andere Flags braucht.


Vielleicht gibt's ja hier den Ein oder Anderen, der selbst in C++ 
entwickelt und mir weiterhelfen kann. :)


Danke schonmal :)

Gruß Marcel

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


Lesenswert?

Was ist denn genau im Binary angekommen?  Hast du's mal disassembliert
oder dir wenigstens die Symboltabelle angesehen?

Btw., {UNIX|GNU} make benutzt per Konvention CXX für den C++-Compiler
und CXXFLAGS für die Compileroptionen dafür.  CPP ist der
C-Präprozessor, CPPFLAGS sind die Optionen für das Präprozessieren.
Spielt bei explizit geschriebenen Regeln zwar keine große Geige, aber
man tut im Allgemeinen gut daran, sich an Konventionen zu halten, weil
das am wenigsten Verwirrung stiftet auf Dauer.

von NurSo (Gast)


Lesenswert?

Blöde Frage,

hast Du nur die Klasse gebaut, oder auch eine Instanz davon erzeugt :-)

von P. S. (Gast)


Lesenswert?

Marcel schrieb:

> Vielleicht gibt's ja hier den Ein oder Anderen, der selbst in C++
> entwickelt und mir weiterhelfen kann. :)

Bestimmt, dafuer muesstest du aber ein uebersetzbares Minimalprojekt und 
wenigstens die Ausgaben eines deiner Versuche posten.

von Marcel (Gast)


Lesenswert?

so, Problem gelöst.

(ja: ich hatte in dem Programm auch ein Objekt von der Klasse erstellt)

woran es lag, weiß ich nicht genau, aber ich nehme an es lag daran, dass 
ich Klasse und Methoden alles in einer .h Datei hatte.

Nach dem ich Klasse und Methoden in .h und .cpp aufgeteilt hatte lief es 
dann.


Danke trotzdem :)

Marcel

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


Lesenswert?

Marcel schrieb:
> woran es lag, weiß ich nicht genau, aber ich nehme an es lag daran, dass
> ich Klasse und Methoden alles in einer .h Datei hatte.

»ich nehme an...«

Assumptions are the root of all evil.

Eine .h-Datei wird durch den Präprozessor genau an der Stelle
reingezogen, wo das #include steht.  Was da drin steht, ist dem
Präprozessor sche***egal, und der Compiler guckt sich nur an, ob
das gültiger C++-Code ist (der bekommt zwar noch eine Info darüber,
dass das aus einem .h stammte, aber die ist nur dafür da, damit er
den Debugger entsprechend leiten kann, sonst interessiert den das
nicht).

Zwar ist es nicht sinnvoll, die komplette Implementierung der Klasse
in eine .h-Datei zu packen (abgesehen von inline-Implementierungen
natürlich), aber solange die .h-Datei nicht von mehreren .cpp-Dateien
reingezogen wird, sollte das keinen Unterschied für den Compiler
ergeben.  In letzterem Falle würdest du aber nicht zu wenig an
Implementierung "sehen", sondern zu viel, d. h. der Linker müsste
sich dann beklagen, dass er bestimmte Dinge zweimal bekommen hat.

von Andreas F. (aferber)


Lesenswert?

Jörg Wunsch schrieb:
> Zwar ist es nicht sinnvoll, die komplette Implementierung der Klasse
> in eine .h-Datei zu packen (abgesehen von inline-Implementierungen
> natürlich), aber solange die .h-Datei nicht von mehreren .cpp-Dateien
> reingezogen wird, sollte das keinen Unterschied für den Compiler
> ergeben.

Ausser der Header wurde irgendwann mal als Kopie von einem anderen 
angelegt und dabei vergessen, den Header-Guard anzupassen. Das kann dann 
zu den lustigsten Effekten führen ;-)

Andreas

von Rolf Magnus (Gast)


Lesenswert?

Andreas Ferber schrieb:
> Ausser der Header wurde irgendwann mal als Kopie von einem anderen
> angelegt und dabei vergessen, den Header-Guard anzupassen.

Oh ja, dieses fiese Problem kenne ich auch. Sowas kann einen echt dazu 
bringen, an sich selbt zu zweifeln.

von Marcel (Gast)


Lesenswert?

Dann war das anscheinend bei mir das Problem.

Ich hatte noch ein anderes Projekt mit der header Datei.
Wenn ich einen Fehler im aktuellen Programm hatte (beim Kompillieren) 
und bin dann zum Problem gesprungen, war ich plötzlich in der 
gleichnamigen header Datei des anderen Projekts.
Habe ich kein Fehler gemacht, wurde die aktuelle header Datei 
verwendet/kompilliert und alles war problemlos.

War schon merkwürdig und ich wusste echt nicht woran es lag.


Gruß

von Karl H. (kbuchegg)


Lesenswert?

Marcel schrieb:
> Dann war das anscheinend bei mir das Problem.

Das lässt sich leicht feststellen:
Benutzt du Include Guards?
Wenn ja, ist dir einer untergekommen, der nicht mit dem 
Dateiinhalt/Dateinamen übereingestimmt hat?


Was auch oft fies ist, sind Include-Pfade die man dem Compiler pauschal 
vorgibt. Da werden dann schon mal includes reingezogen, die man so nicht 
oder von einem ganz anderen Verzeichnis haben wollte.

1 oder 2 Include Pfade sind ok. Ich hab aber auch schon Projekte 
gesehen, bei denen mehr als 20 Include Pfade vorhanden waren, weil die 
verschiedenen Basisfunktionalitäten in entsprechend viele 
Subverzeichnisse aufgeteilt wurden. Da dann nachzuvollziehen, welcher 
include von welchem Verzeichnis kommt, ist eine Sysiphusarbeit.

Moral von der Story: Organisation ist gut. Übertreibt man es aber, dann 
wird sie zum alles behindernden Selbstläufer.

von P. S. (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:

> Moral von der Story: Organisation ist gut. Übertreibt man es aber, dann
> wird sie zum alles behindernden Selbstläufer.

Das Problem an der Story ist ja nicht die Organisation, sondern die 
Faulheit einfach alle Include-Pfade einzubinden, statt die Dateien mit 
Pfad zu includen.

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.