Forum: Compiler & IDEs Anfänger Verständnisproblem: Symbol


von Dietmar (Gast)


Lesenswert?

Hallo, ich habe folgendes Verständnisproblem.
Ich habe 2 Dateien
---------------------------------
#include <avr/io.h>
#define takt 16000000ul

#define test1 PORTB

#include "Datei2.c"

int main (void)
{
 test1 = 0;
}
---------------------------------

und Datei2.c

---------------------------------
void up1 (void)
{
 test1 = 22;
}
---------------------------------

Wenn ich das mit PN kompiliere ist alles OK. Keine Fehler.
Im Makefile habe ich nur den CPU Typ eingestellt alles andere gelassen.

Mache ich das mit einem AVR Studio 4/5/6 oder mit Eclipse unter Linux
gibt es immer den Fehler:

'test1' undeclared (first use in this function)
Dabei ist test1 doch nur ein Symbol und vor dem include definiert ?

Verwende ich aber im AVR Studio/Eclipse das Makefile vom PN,
funktioniert es auch ohne Fehler.
Das kann doch nur eine Kleinigkeit in den Einstellungen sein ?


Auch Beispiele aus einem Buch erzeugen diese Fehler, nicht aber im PN.
Nach stundenlangen lesen und suchen komme ich nun nicht weiter.


Danke

von Peter II (Gast)


Lesenswert?

> #include "Datei2.c"

man includiert keine C dateien sonder header( *.h) dateien.

Du hast das irgendwie verkehrt rum gemacht.

von Noname (Gast)


Lesenswert?

Hm.

Es scheint als wenn die include Datei, wenn Du unter AVR Studio 
kompilierst oder dem Compiler den Du von Eclipse aus aufrufst nicht 
gefunden wird. Allerdings sollten dann noch mehr Fehlermeldungen 
auftauchen, das eben die include-Datei nicht gefunden wird.
Schau mal nach wie die include-Pfade jeweils eingestellt sind, d.h. was 
letzlich der Aufruf des Compilers ist.

Nebenbei: Man includet keine C-Dateien in andere. Die werden jeweils 
einzeln kompiliert und dann am Schluss gelinkt.

von Karl H. (kbuchegg)


Lesenswert?

Dietmar schrieb:

> Auch Beispiele aus einem Buch erzeugen diese Fehler, nicht aber im PN.
> Nach stundenlangen lesen und suchen komme ich nun nicht weiter.

Du hast wahrscheinlich dein main.c und dein Datei2.c in den 
Projekteinstellungen als C-File im Projekt. Damit wird Datei2.c FÜR SICH 
ALLEINE ebenfalls compiliert. Und wenn du dir datei2.c FÜR SICH ALLEINE 
ansiehst, dann stellst du fest: Da fehlt jede Menge.
Logisch: Datei2.c ist nicht dafür gedacht, für sich alleine compiliert 
zu werden.
Und genau das ist einer der Gründe, warum man keine *.c Files 
inkludiert: Man kommt unter anderem durcheinander, welches File für sich 
alleine eine eigenständige Übersetzungseinheit darstellt und welche 
nicht.

von Dietmar (Gast)


Lesenswert?

Danke, also AVR Studio gibt nur diesen einen Fehler aus.
In meinen C - Buch steht bei include "fügt den Inhalt der Datei in das 
Programm ein". Ich dachte, und in meinen AVR Buch kommt das auch vor,
das es auch C Dateien sein können.
Komisch weil es mit PN bzw den PN Makefile geht, wenn es sonst auch 
Header Dateien sein mögen.

Ich lerne ja nur und Ausgangspunkt war eben ein Programm aus dem Buch
mit genau diesem Problem.
Kann sein das der Author hier was falsch gemacht hat.
Also fange ich am besten nochmal neu an.


AVR Studio gibt übrigens folgendes aus:

------ Erstellen gestartet: Projekt: GccApplication1, Konfiguration: 
Release AVR ------
Der Buildvorgang wurde gestartet.
Projekt "GccApplication1.cproj" (Standardziele):
Erstellung mit der Toolsversion 2.0.
Das Ziel "PreBuildEvent" wurde übersprungen, da die Bedingung "false" 
war . ('$(PreBuildEvent)'!='') wurde als (''!='') ausgewertet.
Ziel "CoreBuild" in Datei "C:\Program Files (x86)\Atmel\Atmel Studio 
6.0\Vs\Compiler.targets" aus Projekt 
"C:\Users\dietmar\Documents\AVRStudio 
5.1\Projects\GccApplication1\GccApplication1\GccApplication1.cproj" 
(Ziel "Build" ist davon abhängig):
  Die RunCompilerTask-Aufgabe aus der C:\Program Files (x86)\Atmel\Atmel 
Studio 6.0\Vs\Compiler.Task.dll-Assembly wird verwendet.
  RunCompilerTask-Aufgabe
    C:\Program Files (x86)\Atmel\Atmel Studio 6.0\make\make.exe all
    Building file: .././incl_test1.c
    Invoking: AVR/GNU C Compiler : (AVR_8_bit_GNU_Toolchain_3.4.0_663) 
4.6.2
    "C:\Program Files (x86)\Atmel\Atmel Studio 
6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe" 
-funsigned-char -funsigned-bitfields -Dm  -Os -c -std=gnu99 -MD -MP -MF 
"incl_test1.d" -MT"incl_test1.d" -MT"incl_test1.o"  -mmcu=atmega32 
-o"incl_test1.o" ".././incl_test1.c"
    .././incl_test1.c: In function 'up1':
C:\Users\dietmar\Documents\AVRStudio 
5.1\Projects\GccApplication1\GccApplication1\incl_test1.c(7,2): 'test1' 
undeclared (first use in this function)
C:\Users\dietmar\Documents\AVRStudio 
5.1\Projects\GccApplication1\GccApplication1\incl_test1.c(7,2): each 
undeclared identifier is reported only once for each function it appears 
in
    make: *** [incl_test1.o] Error 1
  Die Ausführung der RunCompilerTask-Aufgabe ist abgeschlossen -- 
FEHLER.
Die Erstellung des Ziels "CoreBuild" im Projekt "GccApplication1.cproj" 
ist abgeschlossen -- FEHLER.
Die Erstellung des Projekts "GccApplication1.cproj" ist abgeschlossen -- 
FEHLER.

Fehler beim Erstellen
========== Build: 0 erfolgreich oder aktuell, Fehler bei 1, 0 
übersprungen ==========

von Noname (Gast)


Lesenswert?

>Danke, also AVR Studio gibt nur diesen einen Fehler aus.

Dann ist es genau wie Karl Heinz, der Ratefuchs, vermutet hat.
In dem fraglichen Projekt wird die Datei incl_test1.c einzeln 
kompiliert, was auch dem normalen Weg entspräche. Lies nochmal sein 
Posting hier: Beitrag "Re: Anfänger Verständnisproblem: Symbol"


>"fügt den Inhalt der Datei in das Programm ein"
>Ich dachte, und in meinen AVR Buch kommt das auch vor,
>das es auch C Dateien sein können.

Das ist korrekt. Wird aber eben nicht mit C-Dateien getan.
Es ist zwar möglich, aber absolut unüblich.

Wenn das mit C-Dateien-include in dem AVR-Buch vorkommt, hast Du 
vielleicht ein Regal das wackelt. Dafür ist's dann noch gut genug.

von Karl H. (kbuchegg)


Lesenswert?

Dietmar schrieb:

> Programm ein". Ich dachte, und in meinen AVR Buch kommt das auch vor,
> das es auch C Dateien sein können.

Das ist prinzipiell auch richtig.
Nur ist nicht alles was technisch möglich ist, auch sinnvoll.

Die Sprache C wurde so designed, dass ein komplettes Programm aus 
mehreren C-Files bestehen kann, wobei jedes C-File für sich als 
abgeschlossene Einheit betrachtet wird.
D.h. jedes C-File kann für sich alleine übersetzt werden, ohne ansehen 
aller anderen C-Files.

Ein Beispiel: Das Projekt in dem ich involviert bin, besteht aus ca 1800 
C-Files (ok, es sind C++ Files, aber das Prinzip ist das gleiche). Die 
alle komplett zu übersetzen dauert ca. 2 Stunden. D.h. es ist nicht 
sinnvoll, wegen ein paar kleinen Änderungen immer alles zu übersetzen. 
Genau das würde aber passieren, wenn es ein 'Hauptfile' gäbe, welches 
die anderen C-Files inkludiert - es müsste immer der komplette Quelltext 
übersetzt werden. Genau das wollen wir aber NICHT. Ich möchte nur dieses 
1 File neu übersetzen, in dem ich eine Änderung mache. Danach lass ich 
mir aus den übersetzten Einheiten ein neues Komplettprogramm erzeugen 
('linken') und hab wieder ein Programm, welches die Änderung beinhaltet 
- in ca 15 Sekunden.

von Tom (Gast)


Lesenswert?

Wenn du eine Meldung <variable> undeclared bekommst hast du dich 
vertippt, ein #include vergessen oder vergessen die Variable zu 
definieren.

Zu deinem Code: test1 ist unbekannt, ich denke du wolltest schreiben:
#define PORTB test1

Falls dann PORTB nicht bekannt sein sollte, hast du vergessen in den 
Projekteigenschaften den richtigen AVR einzustellen.

von Karl H. (kbuchegg)


Lesenswert?

Tom schrieb:
> Wenn du eine Meldung <variable> undeclared bekommst hast du dich
> vertippt, ein #include vergessen oder vergessen die Variable zu
> definieren.
>
> Zu deinem Code: test1 ist unbekannt, ich denke du wolltest schreiben:
> #define PORTB test1

dann wäre test1 aber immer noch unbekannt.

Die Reihenfolge ist
1
#define <Text welcher ersetzt werden soll> <wodurch dieser Text ersetzt werden soll>

von Proxxon (Gast)


Lesenswert?

Dietmar (Gast) schrieb:

> In meinen C - Buch steht bei include "fügt den Inhalt der Datei in das
> Programm ein".

Im Hanser K&R "Programmieren in C", zweite Ausgabe, Kapitel 4.11 "Der 
C-Preprozessor" steht es etwas genauer als in deinem Buch, nämlich so

"Mit #include werden bevorzugt die Deklarationen eines großen Programms 
zusammengehalten. Damit ist garantiert, dass alle Quelldateien mit den 
gleichen Definitionen und Variablendeklarationen arbeiten .."

Einleitend steht dort zuvor unter

4.11.1 Definitionsdateien einfügen

"Durch Einfügen von Definitionsdateien kann man leicht mit Sammlungen 
von #define-Anweisungen und Deklarationen (und anderen Dingen) umgehen."

Das mit dem "Inhalt einfügen" oder ersetzen steht natürlich auch drin. 
Aber dieser Satz alleine wäre zu kurz und missdeutig.

von Tom (Gast)


Lesenswert?

>> Zu deinem Code: test1 ist unbekannt, ich denke du wolltest schreiben:
>> #define PORTB test1

>dann wäre test1 aber immer noch unbekannt.

sorry, stimmt natürlich. Also fehlt nur die Deklarationen für den 
Controllertyp. Entweder durch die Projektoptionen oder z. B.
#include avr/iom8.h
für ATmega8, bzw. andere Datei für anderen AVR

von Peter II (Gast)


Lesenswert?

Tom schrieb:
> sorry, stimmt natürlich. Also fehlt nur die Deklarationen für den
> Controllertyp. Entweder durch die Projektoptionen oder z. B.
> #include avr/iom8.h

nein auch nicht, in der 2. C datei gibt es kein Test weil es in der 1.C 
datei definiert ist. Und der compiler will die 2. C  datei eigenstädnig 
übersetzen.

Das Problem ist doch schon geklärt, er hat versucht eine C Datei zu 
includieren.

von Dietmar (Gast)


Lesenswert?

Hallo, also ich habe jetzt die #define ...in eine Headerdatei 
geschrieben.

#define test1 PORTD

Diese Datei.h dann in meine Datei1 und Datei2 mit #include eingefügt.

Jetzt kann ich im AVR Studio in den Eigenschaften der Dateien festlegen
welche Datei ich Compilieren will.

Habe ich das richtig verstanden ?

Ich dachte es werden immer alle auf einmal übersetzt.

Der Fehler ist jetzt weg.

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.