Forum: Mikrocontroller und Digitale Elektronik ANSI C - Funktion wird nicht kompiliert - Warum?


von svs (Gast)


Lesenswert?

Hallo Leute,

Ich bin noch Anfänger, darum möchte ich mich vorab für "dumme" Fragen 
entschuldigen.
Ich bin weder faul, noch möchte ich meine Hausübung weiterdelegieren.

Bei meinem Compiler (MIKROE) wird der Aufruf einer Funktion nicht 
kompiliert.
Wie ich das merken: Ganz einfach. Egal ob ich den Aufruf ausklammer oder 
nicht, Die Programmgrößße ist immer 1 Byte :-/

Also 1 Byte:
1
void Config(){
2
     ANSELA     = 0;
3
     PORTA      = 0;
4
     TRISA      = 0xCA;
5
     OSCCON = 0x7B;
6
}
7
8
void main() {
9
     Config();
10
}

Und ebenso 1 Byte:
1
void Config(){
2
     ANSELA     = 0;
3
     PORTA      = 0;
4
     TRISA      = 0xCA;
5
     OSCCON = 0x7B;
6
}
7
8
void main() {
9
     //Config();
10
}

Also gehe ich davon aus, dass die Function "Config" nicht compiliert 
wird.
Aber warum?
Ideen?

: Bearbeitet durch Moderator
von Georg G. (df2au)


Lesenswert?

Und der Compiler gibt keine Warnung, keinen Fehler aus?

Zeig doch bitte das GANZE Programm. Der Schnipsel kann so nicht 
übersetzt werden.

von svs (Gast)


Angehängte Dateien:

Lesenswert?

Schon.
Ist komplett.

Wenn ich den Code aus "Config" in die main reinkopier, wächst das 
Kompilat.

von mm (Gast)


Lesenswert?

Ich kenne MIKRÖ nicht, aber 1 Byte ist in jedem Fall zuwenig.
Der startup-Code, der Dein main() aufruft, sollte schon größer sein.

von Johannes F. (Gast)


Lesenswert?

Bei „ANSI C“ müsste es schon mal
1
int main() {...}
heißen. Mir bekannte Compiler erzeugen auch mindestens eine Warnung, 
wenn man „void main()“ schreibt.

von svs (Gast)


Angehängte Dateien:

Lesenswert?

Noch ein offizielles Beispiel.

von Georg G. (df2au)


Lesenswert?

svs schrieb:
> Ist komplett.

und woher kennt der Compiler dann die Adresse von zB ANSELA?
Meine Kristallkugel sagt, dass der Compiler mit einem Fehler abbricht...

von Michael.M (Gast)


Lesenswert?

Hallo,

svs schrieb:
> Also gehe ich davon aus, dass die Function "Config" nicht compiliert
> wird.
> Aber warum?
> Ideen?

Mach erstmal weiter. So hat das noch nichts mit einem Programm im dem 
Sinne zu tun, der Compiler optimiert alles weg!

Für welches System (PC,µController, usw) willst du denn ein C Programm 
schreiben ?

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


Lesenswert?

Johannes F. schrieb:
> Bei „ANSI C“ müsste es schon mal
>
> int main() {...}
>
> heißen.

Nein. Es müsste
1
int main(void) 
oder
1
int main(int argc, char **argv) 
heißen.

Die leere Klammer ist in C nicht gleichbedeutend zu "(void)".

von Michael.M (Gast)


Lesenswert?

Georg G. schrieb:
> und woher kennt der Compiler dann die Adresse von zB ANSELA?
> Meine Kristallkugel sagt, dass der Compiler mit einem Fehler abbricht...

Du hast doch beim erstellen des Programms sicher angegeben was du 
Programmieren möchtest. Wenn deine IDE das nicht automatisch machst must 
du halt auch den #include <µController.h>, so weiß der Compiler was 
ANSELA ist und wo es er das Register findet.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

svs schrieb:

> Angehängte Dateien:
> HodenTest.c

> Schon.
> Ist komplett.

Ich wüsste ja zugern, wie Du damit Deine Keimzellen testetst.
Vermutlich mal wieder ein Fall toxischer Männlichkeit... :-)

Grüßle,
Volker

von svs (Gast)


Angehängte Dateien:

Lesenswert?

Jetzt sollte alles erkennbar sein.
Compiler, Controller,...

Keine Fehler oder ähnliches :-/

von Nachdenklicher (Gast)


Lesenswert?

Ändert sich denn die Zeile drunter mit "Used ROM"?

von Teo D. (teoderix)


Lesenswert?

Was ist mit dem Config-File, das er nicht findet!?

von svs (Gast)


Angehängte Dateien:

Lesenswert?

Macht auch keinen Unterschied :-/

von Johannes F. (Gast)


Lesenswert?

Michael.M schrieb:
> Mach erstmal weiter. So hat das noch nichts mit einem Programm im dem
> Sinne zu tun, der Compiler optimiert alles weg!

Das vermute ich auch. Probiere testweise mal, die Optimierungen zu 
deaktivieren. Müsste in den Einstellungen irgendwo möglich sein.

von svs (Gast)


Angehängte Dateien:

Lesenswert?

Aja. Mit der Config.
Ändert aber nix.

Beitrag #7286555 wurde vom Autor gelöscht.
von svs (Gast)


Lesenswert?

Habe meinen Fehler gefunden. Danke.

von Ralf G. (ralg)


Lesenswert?

svs schrieb:
> Wie ich das merken: Ganz einfach. Egal ob ich den Aufruf ausklammer oder
> nicht, Die Programmgrößße ist immer 1 Byte :-/

Die Programmgröße sind 12 Worte.

Jetzt müsste nur noch jemand sich mit dem 'P12F1572' auskennen, ob das 
vom Startupcode so hin kommt. Denn für die 'Config()' fängt der Compiler 
nicht an, extra 'ne Funktion zu basteln. Das wird einfach nebenbei mit 
'ausgefüllt'.

(Wieso braucht man in dieser 'IDE' eigentlich keine '*.h'?)

von Teo D. (teoderix)


Lesenswert?

Ralf G. schrieb:
> (Wieso braucht man in dieser 'IDE' eigentlich keine '*.h'?)

Klickibunti....

von Johannes F. (Gast)


Lesenswert?

Ralf G. schrieb:
> (Wieso braucht man in dieser 'IDE' eigentlich keine '*.h'?)

Weil das „Device“ beim Anlegen des IDE-Projekts angegeben wird (im 
Screenshot links ersichtlich), und die IDE damit automatisch die 
benötigten Header einbindet. Ist beim Microchip Studio übrigens genauso.

von Hoschti (Gast)


Lesenswert?

svs schrieb:
> Habe meinen Fehler gefunden. Danke.

Und was war's denn jetzt?

von Stefan F. (Gast)


Lesenswert?

svs schrieb:
> Habe meinen Fehler gefunden

Sollen alle anderen, denen das gleiche passiert, selbst erneut nach der 
Fehlerursache suchen?

von Teo D. (teoderix)


Lesenswert?

Hoschti schrieb:
> Und was war's denn jetzt?

Is doch wurscht oder willst Du dieses IDE-Compiler Kladeradatsch, für 
rund 300 Öcken kaufen?!
Das gibts für lau bei Microchip und das erzeugt wenigsten einen 
einigermaßen konformen Code.

von WF88 (Gast)


Lesenswert?

Johannes F. schrieb:
> Bei „ANSI C“ müsste es schon mal
>
> int main() {...}
>
> heißen. Mir bekannte Compiler erzeugen auch mindestens eine Warnung,
> wenn man „void main()“ schreibt.

Ausserdem lässt Ansi keine leeren Argumente zu.
void config(void) ....

von DPA (Gast)


Lesenswert?


von Rolf M. (rmagnus)


Lesenswert?

Jörg W. schrieb:
> Nein. Es müsste
> int main(void) …
> oderint main(int argc, char **argv) …
> heißen.
>
> Die leere Klammer ist in C nicht gleichbedeutend zu "(void)".

Gerade bei main() ist es egal, weil das nur für den Aufrufer relevant 
ist, main() aber nicht explizit aufgerufen wird.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Jörg W. schrieb:
>> Nein. Es müsste
>> int main(void) …
>> oderint main(int argc, char **argv) …
>> heißen.
>>
>> Die leere Klammer ist in C nicht gleichbedeutend zu "(void)".
>
> Gerade bei main() ist es egal, weil das nur für den Aufrufer relevant
> ist, main() aber nicht explizit aufgerufen wird.

In einem hosted-environment (mit OS) sind die Signaturen
1
int main()

und
1
int main(int, char**)

standardisiert. Beliebig viele weitere sind aber möglich durch die 
Implementierung.

In einem freestanding-Environment (bspw. auf µC ohne OS) ist es völlig 
implementation-defined, welche Funktion der entry-point ist. 
Üblicherweise ist es aber
1
[[noreturn]] int main(void)

von Harry L. (mysth)


Lesenswert?

Wilhelm M. schrieb:
> In einem hosted-environment (mit OS) sind die Signaturen
> int main()
>
> und
> int main(int, char**)
>
> standardisiert. Beliebig viele weitere sind aber möglich durch die
> Implementierung.

Nein!
Standardisiert ist
1
int main(int argc, char *argv[])

von Wilhelm M. (wimalopaan)


Lesenswert?

Harry L. schrieb:
> Wilhelm M. schrieb:
>> In einem hosted-environment (mit OS) sind die Signaturen
>> int main()
>>
>> und
>> int main(int, char**)
>>
>> standardisiert. Beliebig viele weitere sind aber möglich durch die
>> Implementierung.
>
> Nein!
> Standardisiert ist
>
1
> int main(int argc, char *argv[])
2
>

Nö. Schau nach unter

C-Standard:
5.1.2.1 Freestanding environment und
5.1.2.2.1 Program startup

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> In einem hosted-environment (mit OS) sind die Signaturen
>
> int main()

In C++ ist "int main()" gleichbedeutend mit "int main(void)". In C ist 
es das nicht.

Harry L. schrieb:
> char *argv[]

… ist dasselbe wie "char **argv". Die void-Version ist trotzdem auch 
explizit vom Standard vorgesehen.

Rolf M. schrieb:
> Gerade bei main() ist es egal, weil das nur für den Aufrufer relevant
> ist, main() aber nicht explizit aufgerufen wird.

Naja, habe nicht nachgeguckt, aber könnte genau genommen undefined 
behaviour sein, wenn man es nicht so deklariert. Außerdem wird es 
natürlich in vielen Fällen schon aufgerufen als
1
exit(main());

Selbst im Startup-Code der avr-libc ist das so, nur dass es dort kein 
argc/argv als Argument gibt. Prinzipiell würde es der Anwendung sogar 
offen stehen, in .init8 noch argc (in r24/r25) und argv (r26/r27) 
passend zu setzen. ;-)

von Rolf M. (rmagnus)


Lesenswert?

Harry L. schrieb:
> Nein!

Hier der Originaltext von
https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf

"The function called at program startup is named main. The 
implementation declares no prototype for this function. It shall be 
defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any 
names may be used, as they are local to the function in which they are 
declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent or in some other implementation-defined manner."

Man beachte insbesondere die letzte Zeile.

Jörg W. schrieb:
> Rolf M. schrieb:
>> Gerade bei main() ist es egal, weil das nur für den Aufrufer relevant
>> ist, main() aber nicht explizit aufgerufen wird.
>
> Naja, habe nicht nachgeguckt, aber könnte genau genommen undefined
> behaviour sein, wenn man es nicht so deklariert.

Nein, allerdings wohl implementation-defined, siehe oben.

> Außerdem wird es natürlich in vielen Fällen schon aufgerufen al
> exit(main());

Hmm, hab ich noch nie gesehen. In C++ wäre das verboten. Da ist explizit 
vorgegeben, dass man main() nicht aufrufen darf, aber diese Regel 
scheint es in C nicht zu geben.

> Selbst im Startup-Code der avr-libc ist das so, nur dass es dort kein
> argc/argv als Argument gibt.

Naja, Startup-Code ist dann doch noch was anderes, da Teil der 
Implementation.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> In C++ ist "int main()" gleichbedeutend mit "int main(void)". In C ist
> es das nicht.

Das ist klar.
Aber hier geht es um C und nicht um C++.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Man beachte insbesondere die letzte Zeile.

Genau das habe ich oben geschrieben und die entsprechenden Kapitel im 
C-Standard benannt. Das gilt wie gesagt in einem hosted-environment.

Bei freestanding ist das anders (s. mein Beitrag oben).

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Rolf M. schrieb:
>> Man beachte insbesondere die letzte Zeile.
>
> Genau das habe ich oben geschrieben und die entsprechenden Kapitel im
> C-Standard benannt.

Ich hab's lieber direkt zitiert, weil ich vermute, dass einige doch 
nicht nachschlagen, sondern lieber weiter hier was anderes behaupten.

> Das gilt wie gesagt in einem hosted-environment.
>
> Bei freestanding ist das anders (s. mein Beitrag oben).

Ja. Den Teil hab ich jetzt nicht extra mit zitiert.

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


Lesenswert?

Wilhelm M. schrieb:
> Das ist klar.
> Aber hier geht es um C und nicht um C++.

Deshalb solltest du auch "int main(void)" schreiben.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Wilhelm M. schrieb:
>> Das ist klar.
>> Aber hier geht es um C und nicht um C++.
>
> Deshalb solltest du auch "int main(void)" schreiben.

Das stimmt natürlich, danke. Und das meinte ich eigentlich auch.

Da war ich wohl in Gedanken bei den beliebigen anderen Signaturen, die 
der Standard explizit als implementation-defined erlaubt :-)

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.