Grade ist hier was sehr skurriles passiert... ich habe eine Funktion namens 'verstaerkung' geschrieben. Deklariert, definiert, in main aufgerufen. Der Compiler meldetet "implicit definition of verstaerkung". Erster Gedanke: Der Name ist zu lang (aus welchem Grund auch immer). So wurde aus 'verstaerkung' sukzessive 'versta'. Aber die Meldung blieb. Dann traf mich irgend ein Inspirationspartikel und ließ mich das 'v' am Anfang entfernen. Aus 'versta' wurde 'ersta' - und, siehe da, es ging plötzlich. Hat hier vielleicht jemand eine Erklärung für dieses Phänomen?!? Gruß, Harald
Daß der Compiler kein 'v' als ersten Buchstaben des Funktionsnamen akzeptiert, oder daß 'verstaerkung' zu lang wäre, das kann beides mit Sicherheit ausgeschlossen werden. Das klingt eher nach Aufruf der Funktion ohne vorheriges Bekanntgeben durch einen Prototypen. Abhilfe: entweder Funktionsdefinition im Sourcecode vor den Aufruf packen oder Funktionsdeklaration (Prototyp) vor den Aufruf packen: Erste Variante: void bla(void) { //... } int main(int argc, char **argv) { bla(); } Zweite und bessere Variante: // Prototyp void bla(void); int main(int argc, char **argv) { bla(); } void bla(void) { //... }
Hi Also mein GCC hat kein Problem mit der Funktion "verstaerkung", alles andere hätte mich auch überrascht. void verstaerkung(void); // funzt bei mir Da ist sonst was falsch, entweder ein Tippfehler, deklaration ohne Parameter (z.B. fehlendes void), oder ein Funktions-Aufruf vor der Funktions-Deklaration... Gruss Peter
Hi, das ist ja das skurrile - die Deklaration steht korrekt am Anfang des Quellcodes, mit Parametern und so weiter. (Ich kann den Code leider nicht posten, der betreffende Rechner ist mangels Netzanschluss bis auf weiteres leider eine Einwegdatensenke). Danach kommt die Definition; danach der Aufruf in main. Schreibfehler konnte ich mittels Suchfunktion ausschließen. Und, wie gesagt, nachdem der erste Buchstabe weg war, ging´s plötzlich. Hab das auch alles zusammen mit einem sehr erfahrenne Kollegen überprüft. Ich werd´mal einige weitere Experimente machen. Gruß, Harald
Es muss an was anderem liegen... - Gross/Keinschreibung? - Synthax-Fehler [; , { } ( )]? - Ist der Funktionsname sonst noch irgendwo definiert? (Search in Files Funktion ?) - Versuche ein "make clean" bzw. "rebuilt built all", (Dependencies über Macros werden z.B. nicht automatisch erkannt) Sonst musst Du den Code doch irgenwie posten...
_ die Deklaration steht korrekt am Anfang des Quellcodes, mit Parametern und so weiter. _ Hehe. Prototypen Schreibt man ohne Parameter. zB int bla(int, char, char, int); funktion: int bla(int a, char b, char c, int d) { //Tut }
"Prototypen Schreibt man ohne Parameter." Geht beides. Mit ist meist verständlicher.
Schick's doch mal durch den Präprozessor... (avr-gcc ... -E). Wenn du alle Arten von Schreibfehlern konsequent ausschließen kannst, dann würde ich fast meine nicht vorhandene Perücke drauf verwetten, dass du irgendwo ein #define verstaerkung foobar hast. Wenn du dann void verstaerkung(void); deklarierst, deklarierst du natürlich in Wirklichkeit void foobar(void);
> Prototypen Schreibt man ohne Parameter. > > zB > > int bla(int, char, char, int); Wieso? Da stehen die Parameter doch. Zwar ohne Namen, aber die werden eh ignoriert. Man kann sie zwar tatsächlich auch ohne Parameter deklarieren, aber das empfielt sich nicht. }
@Harald Horn: Mach's doch nicht so schwer und poste einfach Deinen konkreten Code. Du hast zu 100% einen Fehler drinn.
> Hehe. > Prototypen Schreibt man ohne Parameter. Schon. Ist von der Sprache her erlaubt. Nur wenn Du das tust, bist Du Deinen Job los :-)
Hab ich mir jetzt wohl ganz schöne Rügen mit eingesammelt mit der Aussage. In meinem C Buch für die Schule stand, Prototypen werden wie Funktionsnamen geschrieben aber ohne Parameternamen. Darauf habe ich mich bei der Aussage gestützt. Nun gut, zugegeben, ich ändere gleich mal meine Programme um, ist nämlich in der Tat besser :-)
@Karl Heinz, in was fuer nem Laden wird man fuer das Weglassen der Parameternamen im prototype rausgeschmissen, abgemahnt oder zumindest abgewatscht ?
In Läden, in denen auf brauchbar kommentierten und dokumentierten Quelltext geachtet wird.
:) Das ist ja fast klingonisch. Mein Kommentar ist alles was man an Doku braucht oder wie ? Wir benutzen java-doc tags, geschriebene Doku und natuerlich machen die parm namen den code besser lesbar. Aber gleich die Spanische Inquisition auf den Plan zu rufen, wenn ein parm mal nicht benannt wird ... oha !
Hi mal ein hypotetischer Codeschnipsel mit Kommentar:
1 | /**
|
2 | * Calculates the volume of a cylinder
|
3 | *
|
4 | * @param hight
|
5 | * @param radius
|
6 | */
|
7 | float calcCylinderVolume(float, float); |
Ist ein gültiger Prototyp. Die Funktion ist fertig kompiliert in einer Bibliothek. In welchen Parameter kommt jetzt der Radius und in welchen die Höhe? Paramternamen kann man zwar in Prototypen weglassen man sollte es aber unbedingt vermeiden. Matthias
> @Karl Heinz, > in was fuer nem Laden wird man fuer das Weglassen der > Parameternamen im prototype rausgeschmissen, abgemahnt oder > zumindest abgewatscht ? Wenn Du in meiner Gruppe arbeitest. Zuerst wirds einem freundlich erklaert, dann schon etwas heftiger und wenn alles nichts hilft: Tut uns leid. Den Ueberblick ueber 15000 Funktionen zu behalten ist so schon schwer genug. Da brauch ich nicht auch noch Ratespiele.
Alles klar, nagelt mich bitte nicht gleich ans Kreuz. Ich hatte mich nur über Karl Heinz drakonische Strafen gewundert.
> mal ein hypotetischer Codeschnipsel mit Kommentar:
1 /**
2 * Calculates the volume of a cylinder
3 *
4 * @param hight
5 * @param radius
6 */
7 float calcCylinderVolume(float, float);
Doxygen-Kommentare kommen aber besser in die Definition, nicht in die
Deklaration. Die Definition hat aber immer Parameternamen...
Ist übrigens zwiespältig. In meinem eigenen Code würde ich die Namen
wohl immer mitschreiben. In Bibliothekscode (z. B. als avr-libc-
Maintainer) ist das nicht mehr so ohne weiteres möglich, da ein
beliebig erfundener (aussagekräftiger) Name ja im application
namespace liegt. Man denke an sowas:
1 | void *memcpy(void *dest, void *src, size_t len); |
Wenn dann in der Applikation davor ein #define len strlen(msg) steht, ist das nicht mehr so lustig... In der avr-libc haben wir daher alle Parameternamen mit führenden Unterstrichen geschrieben, was wiederum in der Doku nicht so nett aussieht. Wenn mal jemand viel lange Weile hat, sollte man die Doku aber besser aus den Headerfiles in die Implementierungsdateien ziehen und in den Headers dann die Parameternamen einfach weglassen.
Interessanter Aspekt, daran hatte ich noch garnicht gedacht. Aber wenn du die tags aus der header file rausnimmst, dann legt man natürlich solch angenehme Sachen wie tagging im Visual SlickEdit aufs Kreuz. Scheint als gäbe es keine perfekte Lösung.
Hi @Jörg Über die platzierung von doxygen-Kommentaren kann man geteilter Meinung sein. Ich platziere sie ganz gerne zur Deklaration ins Headerfile da genau diese Datei die Schnittstellenbeschreibung enthält. Brauch ich also eine Information zu dieser Schnittstelle ist diese Datei auch mein erster Anlaufpunkt. Mit den aus den doxygen-Kommentaren erstellten Dokumenten arbeite ich nur sehr selten bzw. wenn ich mir einen Überblick über größere Zusammenhänge schaffen will. #define len strlen(msg) Wer sowas macht braucht sich nicht zu wundern das was nichtmehr funktioniert. Präprozessormakros schreib ich nur mit Großbuchstaben (das ist wohl fast überall so üblich). Im Quellcode selber entweder aaa_bbb_ccc oder aaaBbbCdd und schon sind sämtlicher Kollisionen dieser Art ausgeschlossen. Matthias
> Präprozessormakros schreib ich nur mit Großbuchstaben > (das ist wohl fast überall so üblich). Nö. Eigentlich nur für Konstanten und Makros mit Seiteneffekten. OK, strlen(msg) hat natürlich einen solchen. ;-) Gerade bei den Makros, die wie Funktionen behandelt werden, sind Kleinbuchstaben nicht unüblich, siehe getc() in der stdio-Bibliothek. Es ging ja auch nur ums Prinzip, als Bibliothekshersteller darf ich mich einfach nicht auf die Freundlichkeit der Benutzer verlassen.
> Nö. Eigentlich nur für Konstanten und Makros mit Seiteneffekten. Also bei mir ist es üblich für alle Makros und nur für diese. Ich programmiere aber auch viel in C++ (mittlerweile auch auf AVR), wo bei Makros noch das eine oder andere Problemchen dazukommt (z.B. daß sie sich nicht um Namespaces scheren). Außerdem braucht man in C++ eh nur selten Makros. Da finde ich es durchaus praktisch, wenn ich ein Makro als solches sofort anhand seines Namens erkenne. > OK, strlen(msg) hat natürlich einen solchen. ;-) > Gerade bei den Makros, die wie Funktionen behandelt werden, sind > Kleinbuchstaben nicht unüblich, siehe getc() in der > stdio-Bibliothek. Das heißt allerdings nicht, daß es eine gute Idee ist. In der Standarbibliothek hängt eh so einiges schief.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.