www.mikrocontroller.net

Forum: Compiler & IDEs GCC mag kein führendes 'v' im Funktionsnamen?


Autor: Harald Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)
  {
    //...
  }

Autor: Peter Sager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Harald Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Sager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
_
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
}

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Prototypen Schreibt man ohne Parameter."

Geht beides. Mit ist meist verständlicher.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.
}

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Harald Horn:

Mach's doch nicht so schwer und poste einfach Deinen konkreten Code.

Du hast zu 100% einen Fehler drinn.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hehe.
> Prototypen Schreibt man ohne Parameter.

Schon. Ist von der Sprache her erlaubt.
Nur wenn Du das tust, bist Du Deinen Job los
:-)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz,
in was fuer nem Laden wird man fuer das Weglassen der Parameternamen im
prototype rausgeschmissen, abgemahnt oder zumindest abgewatscht ?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Läden, in denen auf brauchbar kommentierten und dokumentierten
Quelltext geachtet wird.

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:) 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 !

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

mal ein hypotetischer Codeschnipsel mit Kommentar:
/**
 * Calculates the volume of a cylinder
 *
 * @param hight
 * @param radius
 */
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> @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.

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar, nagelt mich bitte nicht gleich ans Kreuz. Ich hatte mich nur
über Karl Heinz drakonische Strafen gewundert.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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:
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.

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Lt.Cmdr. Data (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.