Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Frage zu gcc.

1 view
Skip to first unread message

Anton Müller

unread,
Jan 4, 2009, 5:23:51 PM1/4/09
to
Hallo,

ich hab heute wieder mal ein kleines (Übungs)Programm aus der Mottenkiste
geholt, welches ich vor längerer Zeit einmal schrieb, und wollte dieses mit
dem gcc 4.1.2 20061114 (prerelease) (Debian 4.1.1-21) kompilieren.

Mit welchem Compiler ich das Programm damals kompiliert hatte, das kann ich
heute nicht mehr sagen, tut auch nix zur Sache.

Auf jedenfall wird vom Kompiler eine Fehlermeldung ausgegeben, daß die
Funktion pow(x,y) (zum Potenzieren x^y), die normalerweise in der math.h
definiert ist, nicht definiert sei, und das, obwohl ich die math.h
includiert hab.

Mit google hab ich rausgefunden, daß man für das Kompilieren dieser
Funktion noch die Optionen -lm setzen muß, so dass die Befehlszeile
gcc -o rundatei -lm quellcode.c heißen muß, was dann auch funktioniert hat.

Dennoch hätte ich gerne gewußt, wozu die Optionen -lm nötig sind, bzw was
es damit aufsich hat, weshalb die in diesem Falle nötig ist, wo ich doch
die math.h includiert hab. Dummerweise ist auf meinem System die man gcc
"kaputt" und aus der man-page aus dem Internet werd ich auch nicht richtig
schlau.

Aber vielleicht kann mir ja hier jemand sagen, welche Bewandnis es mit den
Optionen -lm auf sich hat.

Ach ja, falls es jemanden interessiert, hier mein Übungsprogramm,
selbstgestrickt und funktionsfähig!

/*Projekt - Umwandlung Hex-Zahlen in Zezimalzahlen - */
/*Ver. 2*/
//Kompilerinfo für Linux gcc
// muß mit gcc -o ausfuerbare Binary -lm xx.c kompiliert werden
// -lm wurde notwendig wegen der Funktion pow.
// und einem Wincompiler war das wohl nicht nötig...???
// Fehler durch Begrenzung der Anzahl der Eingabezeichen begrenzt
#include<stdio.h>
#include<math.h>
#define MAX_LENGTH 7
//MAX_LENGTH AUF 6 = 7 Zeichen heruntergesetzt (war vorher auf 13 gesetzt.)
#define NEIN 0
#define JA 1

int main(void){
char a[MAX_LENGTH];/*Eingangsvektro*/
char ab [MAX_LENGTH]; /*Zwischenvektor*/
int abc [MAX_LENGTH];
loop:;/*um belieg oft eine Zahl einzugeben*/
long erg=0;
char b;
int i=0;/*Eingangszähler*/
int j; /*Zwischenzaehler*/
int k=0; /*Umsetzungszaehler*/
int tolong=NEIN;

printf("\n\n\n\n\n\n\n\n\n\nEine hexadezimale Zahl mit maximal sieben
Zeichen eingeben.\n Erlaubt sind die Zeichen [0..9|a...f|A...F]\n");
while((b=getchar())!='\n'){/* Zahl einlesen*/
//whileschleife wird nach Return für jede Stelle durchlaufen
//so lange, bis ein Return bzw ein '\n' erfolgt

if(i<=(MAX_LENGTH-1)){//so lange wie die Maximallänge nicht
//erreicht ist, wird der Eingabebuffer ausgelesen
a[i++]=b;
//und in den Vektor a[] abgespeichert
}
else{//Eingabe wurde zu lang
tolong=JA;
printf("\n\nEingegebene Zahl zu lang\n\n\n");
//return 1;
while(getchar()!='\n');//Tastatrupuffer leeren, bis Returnzeichen
gefunden
goto loop; //erneuter Eingabeversuch
}
}


for (j=i-1;j>=0;--j){/*Umdrehung des Eingagsvektors, so das die
niederwertigste Stelle an Platz 0 steht */
ab[k++]=a[j];
/*printf("\nHier ... %c\n",a[j]);*/
}

for (j=0;j<=i-1;++j){/*Umwandlung der Hexziffern in Dez-ziffern*/
/* printf("ppp111\n\n");
printf("%c\n\n",ab[j]);*/
if(ab[j]>='0' && ab[j]<='9'){//Abfrage ob ein Zeichen von 0...9
/*printf("hier");*/
abc[j]=ab[j]-'0'; //Wertzuweisung
}
else{
if(ab[j]>='a' && ab[j]<='f'){//Abfrage ob Zeichen von a...f
abc[j]=ab[j]-'a'+10;//Wertzuweisung
}
else{
if(ab[j]>='A' && ab[j]<='F'){//Abfrage ob Zeichen von A...F
abc[j]=ab[j]-'A'+10;
}
else{
printf("Ungueltiges Zeichen\n\n");
//return 0;
goto loop; //Ungültiges Zeichen, neuer Versuch von Anfang!
}
}
}
}
for (j=0;j<=(i-1);++j){/*Aufaddierung der Stellen*/
//i=Anzahl der Stellen, j=Exponent der 16er Basis, abc[] befinden sich die
//Multiplikatoren für die jeweilige Stelle
erg=erg + abc[j]*pow(16,j);//Bereichnung des jeweiligen
Stellenergebnisses und Aufaddierung
}

printf("\n\nErgebnis= %d\n\n",erg);
//return 0;
goto loop;
}


Anton

Juergen Wieferink

unread,
Jan 5, 2009, 2:49:10 AM1/5/09
to
> Auf jedenfall wird vom Kompiler eine Fehlermeldung ausgegeben, daß die
> Funktion pow(x,y) (zum Potenzieren x^y), die normalerweise in der math.h
> definiert ist, nicht definiert sei, und das, obwohl ich die math.h
> includiert hab.
>
> Mit google hab ich rausgefunden, daß man für das Kompilieren dieser
> Funktion noch die Optionen -lm setzen muß, so dass die Befehlszeile
> gcc -o rundatei -lm quellcode.c heißen muß, was dann auch funktioniert
> hat.

Du hast es hier mit C zu tun. Da will zum einen der Kompiler einen
Prototypen [ double pow(double, double); ] für eine Funktion haben,
der in math.h enthalten ist. Deswegen #include <math.h>. Zum
anderen muss der Linker diese Funktion aber auch in die ausführbare
Datei mit aufnehmen. Und pow() steckt nunmal in der Mathebibliothek
libm.a (Unix), die mit "-lm" eingebunden wird.

Jürgen

Anton Müller

unread,
Jan 5, 2009, 6:17:47 AM1/5/09
to

Ich dachte, die math.h sei bereits die Mathebibliothek, in der pow()
enthalten sei....zumindst hab ich das so nach K&R in Erinnerung...
(...musssich doch gleich noch mal nachgucken...)

Ist das jetzt mit libm.a eine Besonderheit unter Unix oder des gcc's?

Danke für Erläuterung.

mfG Anton

Juergen Wieferink

unread,
Jan 5, 2009, 6:31:29 AM1/5/09
to
Anton Müller wrote:
> Ich dachte, die math.h sei bereits die Mathebibliothek, in der pow()
> enthalten sei....zumindst hab ich das so nach K&R in Erinnerung...
> (...musssich doch gleich noch mal nachgucken...)

Nein.

> Ist das jetzt mit libm.a eine Besonderheit unter Unix oder des gcc's?

Nein.

Es mag sein, dass einige integrierte Benutzerumgebungen selbsttätig
erkennen, dass die Mathebibliothek mit eingebunden werden muss.

Mach dich am besten mit dem Unterschied von kompilieren und linken
vertraut. Es ist nämlich sogar so, dass man statt

#include <math.h>

auch

double pow(double a, double b);

schreiben könnte. Das ist alles, was der Kompiler wissen muss.
Solange man dem Linker dann mit -lm die Mathebibliothek mitgibt,
wird das funktionieren.


Juergen

Stefan Reuther

unread,
Jan 5, 2009, 11:51:17 AM1/5/09
to

"Die Mathebibliothek" ist im Kontext von C und Unix so ein schwammiges
Nullaussagewort.

Wenn du ein C-Programm mit mehreren Modulen schreibst, musst du die ja
auch an zwei Stellen einbinden. Du musst die Headerdatei 'blafasel.h'
einbinden, damit der Compiler weiß, wie er deine Funktionen aufrufen
soll, und du musst beim Linken deines Programms mit angeben, dass er die
aus 'blafasel.c' entstandene Objektdatei mit einbauen soll.

Bei der "Mathebibliothek" ist das prinzipiell genauso. Du bindest zum
einen die Headerdatei ein, und sagst zum anderen mit '-lm', dass du die
entsprechenden Objektdateien haben willst. 'libm.a' ist sowas wie eine
Objektdatei, genauer gesagt eine Sammlung solcher.

> Ist das jetzt mit libm.a eine Besonderheit unter Unix oder des gcc's?

Ein normaler C-Compiler linkt verschiedene Komponenten der Standard-
Bibliothek automatisch dazu (du musst ja, wenn du <stdio.h> benutzt,
auch nichts extra angeben). Die Mathematik-Funktionen gehören unter Unix
traditionell nicht dazu. Insofern ist das eine Besonderheit von Unix.


Stefan

0 new messages