GCC mag kein führendes 'v' im Funktionsnamen?

Gast #284196
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
Persönliche Seite #284197
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)
  {
    //...
  }
Gast #284198
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
Gast #284199
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
Gast #284200
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...
Moderator Persönliche Seite #284203
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);
Gast #284204
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.
}
Persönliche Seite #284207
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 :-)
Gast #284210
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 !
Persönliche Seite #284211
Lesenswert?

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
#284212
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.
Moderator Persönliche Seite #284214
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:
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.
Gast #284215
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.
Persönliche Seite #284216
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
Moderator Persönliche Seite #284217
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.
Gast #284218
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren