[Megoldva] Egész szám gyöke C-ben?

Fórumok

Sziasztok!

Ezzel a kóddal kínlódok:


#include math.h  // én vettem ki a kacsacsőröket!
#include stdio.h
#include stdlib.h
#include ctype.h

#define FALSE 0
#define TRUE  1

int foo(int szam) {
    int boolVal = FALSE;
    double a1, a2;

    a1 = szam;
    a2 = sqrt(a1);

    return boolVal;
}

int main() {

  return 0;
}

Hibának ezt írja:

CMakeFiles/p007_gyok.dir/main.o: In function `foo':
main.c:(.text+0x3a): undefined reference to `sqrt'

Ugyanakkor, ha a1 értékadásánál egy konstans értéket adok meg, lefordul a program hiba nélkül.

Pl.:


#include math.h
#include stdio.h
#include stdlib.h
#include ctype.h

#define FALSE 0
#define TRUE  1

int foo(int szam) {
    int boolVal = FALSE;
    double a1, a2;

    a1 = 4.345;
    a2 = sqrt(a1);

    return boolVal;
}

int main() {

  return 0;
}

Miért nem fordul le az első esetben? a1-et átkonvertálná egész típusúra? Nem az egésznek kellene double típusúvá konvertálódni?

Hozzászólások

Így első ránézésre, hiányzik a fordítónak a -lm opció.
A tippem az, hogy második esetben, mint felesleges dolgot, ami úgysem hívódik meg, kioptimalizálja a fordító az sqrt-t, azért nem hiányzik linkelésnél.
A #define TRUE 1-el csak a gondok lesznek. Jobb választás a #define TRUE !FALSE

Érdekes jelenséget vettem észre. Ha úgy módosítom a másodikat, hogy az sqrt mindenképp lefusson (meghívom foo-t, és az sqrt után kiíratom az a2-t), és simán lefordítom, akkor a várakozásnak megfelelően nem talája az sqrt fv-t. De ha -O2-vel (-Os -O1 -O3 is) fordítom, akkor nem panaszkodik, lefordul, és helyesen működik. A -Ox paraméter megadásánál automatikusan linkeli a libm-et?

$ gcc --version
gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

A -Ox paraméter megadásánál automatikusan linkeli a libm-et?
Nem, de forditas kozben, mivel az a1=... ertekadas es az sqrt() kozott senki sem piszkalhat bele az a1 valtozo ertekebe, ki tudja szamolni maga a fordito is a gyokvonas eredmenyet. Kiszamitja, igy nem kell a libm-ben levo" sqrt()-t hasznalnia. Ha az a1, a2-t volatile-kent deklaralod, akkor mar -O* optimalizacional is kell a -lm, mert ekkor a fordito nem feltetelez(het)i hogy az a1=... es az sqrt() kozott valaki (egy masik sza'l, pl) nem buzeralja az a1 erteke't. Bar ez mondjuk nem is a peldabeli esetben lehet durva, mert egy belso automatikus valtozot mas szallal/processzel is modositani kicsit meredek. Hanem egy globalis valotozo eseten, ott ez elegge megszokott (mondjuk globalisokat hasznalni is kicsit meredek, de ez mas kerdes :)).

http://gcc.gnu.org/gcc-4.3/changes.html#mpfropts

Amint itt látható, az sqrt-t, és a cabs-t már régóta, az összes többit 4.3-tól tudja optimalizálni a gcc.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

-lm opcióval nálam is jó a program.

Mi is ez a libm? A matematikai függvényeket tartalmazó könyvtár?