# [C++] kompilator mi cuda wywala

## Yatmai

Kurcze chłopaki pomóżcie, bo mnie coś weźmie  :Sad: 

Dorwałem fajny tutorial i doszedłem do wniosku, że warto by trochę lepiej poznać C. Pisałem troche w Pascalu, znam też podstawy C++ z Symfonii C++ Grębosza, więc nie miałem problemów z interpretowaniem przykładów z tutoriala. Przepisuję jedynie co ciekawsze przykłady, zawierające w sobie coś nowego, sęk w tym, że mi się świntuchy sypią. Przykładowy progs:

```
#include <ctime>

#include <iostream>

#include <conio.h>

#include <ctime>

#include <math.h>

enum BIORYTHM {   BIO_PHYSICAL = 23,

      BIO_EMOTIONAL = 28,

      BIO_INTELECTUAL = 33 };

const double PI = 3.1415926538;

double Biorytm(double fDni, BIORYTHM Cykl)

{

   return 100 * sin((2 * PI / Cykl) * fDni);

}

int main()

{

   tm DataUrodzenia = { 0, 0, 0, 0, 0, 0, 0, 0 };

        tm AktualnyCzas = { 0, 0, 0, 0, 0, 0, 0, 0 };

        tm RoznicaCzasu = { 0, 0, 0, 0, 0, 0, 0, 0 };

   std::cout << "Podaj date urodzenia" << std::endl;

   std::cout << "- dzien: ";

   std::cin >> DataUrodzenia.tm_mday;

   std::cout << "- miesiac: ";

   std::cin >> DataUrodzenia.tm_mon;

   DataUrodzenia.tm_mon--;

   std::cout << "- rok: ";

   std::cin >> DataUrodzenia.tm_year;

   DataUrodzenia.tm_year -= 1900;

   time_t Czas = time(NULL);

   AktualnyCzas = *localtime(&Czas);

   RoznicaCzasu.tm_mday = AktualnyCzas.tm_mday - DataUrodzenia.tm_mday;

        RoznicaCzasu.tm_mon = AktualnyCzas.tm_mon - DataUrodzenia.tm_mon;

        RoznicaCzasu.tm_year = AktualnyCzas.tm_year - DataUrodzenia.tm_year;

   double fPrzezyteDni = RoznicaCzasu.tm_year * 365.25

            + RoznicaCzasu.tm_mon * 30.4375

            + RoznicaCzasu.tm_mday;

   

   std::cout << std::endl;

   std::cout << "Twoj biorytm" << std::endl;

   std::cout << "- fizyczny: " << Biorytm(fPrzezyteDni, BIO_PHYSICAL) << std::endl;

   std::cout << "- emocjonalny: " << Biorytm(fPrzezyteDni, BIO_EMOTIONAL) << std::endl;

   std::cout << " intelektualny: " << Biorytm(fPrzezyteDni, BIO_INTELECTUAL) << std::endl;

//   getch();

}

```

Nikt nie jest doskonały, więc nie zdziwiłem się jak po przepisaniu kompilator mi się wysypał. No ale oki, poprawiam literówki, dorzucam nagłówki, błędów w stylu:

```
biorytm.cpp: In function 'double Biorytm(double, BIORYTHM)':

biorytm.cpp:15: error: 'sin' was not declared in this scope

```

 ubywa i nagle dostaję miłe... no nie wiem nawet co to, spam czy jak ?  :Very Happy: 

```

art@exunomei ~/progz $ gcc biorytm.cpp -o biorytm

/tmp/ccbW4ke3.o: In function `__static_initialization_and_destruction_0(int, int)':

biorytm.cpp:(.text+0x23): undefined reference to `std::ios_base::Init::Init()'

/tmp/ccbW4ke3.o: In function `__tcf_0':

biorytm.cpp:(.text+0x6c): undefined reference to `std::ios_base::Init::~Init()'

/tmp/ccbW4ke3.o: In function `Biorytm(double, BIORYTHM)':

biorytm.cpp:(.text+0x9e): undefined reference to `sin'

/tmp/ccbW4ke3.o: In function `main':

biorytm.cpp:(.text+0x10c): undefined reference to `std::cout'

biorytm.cpp:(.text+0x111): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'

biorytm.cpp:(.text+0x119): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'

biorytm.cpp:(.text+0x121): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))'

biorytm.cpp:(.text+0x130): undefined reference to `std::cout'

biorytm.cpp:(.text+0x135): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'

<<<<tu ze 30 podobnych linijek>>>>

biorytm.cpp:(.text+0x366): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(double)'

biorytm.cpp:(.text+0x36e): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'

biorytm.cpp:(.text+0x376): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))'

/tmp/ccbW4ke3.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'

collect2: ld returned 1 exit status

art@exunomei ~/progz $      
```

Linkowanie, pliki *.o i jakieś dziwne komentarze do tego... Kurde, tego już konkret nie łapię jak załatać, a co dziwne dzieje się tak we wszystkich przykładach jakie przepisuje (choc co ciekawe, jak sam od zera napisałem program do zabawy tablicami to ruszył od strzału  :Wink:  ) no i cholerka nie mam jak się pouczyc w praktyce.

Za młodu sporo pisałem w pascalu i tam jakoś błędy wywalane były w jakiś bardziej ludzki sposób i zawsze udawało mi się to jakoś załatać. Byłbym wdzięczny za garść hint'ów albo jakiegoś linka gdzie by mi łopatologicznie wytłumaczyli co zrobić z tymi *.o  :Smile: 

----------

## mziab

Próbówałeś skompilować za pomocą g++, a nie gcc?

----------

## Yatmai

O w morde, ten wklejony przeszedł od strzału....

Tylko w poprzednim przykładzie ze stringami miałem te same objawy i g++ nie pomogło  :Sad: 

----------

## no4b

Musisz zlinkować z biblioteką matematyczną jeżeli chcesz używać funkcji sinus, dodaj -lm do opcji kompilatora.

BTW. zadeklarowałeś, że Twój main zwraca int, a wcale tego nie robi, nieładna praktyka. conio.h też nie masz co załączać, w Linuksie chyba żadna biblioteka ani program nie dostarcza takiego nagłówka.

----------

## Belliash

conio.h to wynalazek borlanda...

do tego bylo cos dla djgpp na sf.net...

----------

## znal

można ew. użyć ncurses zamiast conio

----------

## no4b

Albo napisać swóją funkcję getch z wykorzystaniem termiosa (jakieś 8-9 linikek).

----------

## Yatmai

 *no4b wrote:*   

> BTW. zadeklarowałeś, że Twój main zwraca int, a wcale tego nie robi, nieładna praktyka. conio.h też nie masz co załączać, w Linuksie chyba żadna biblioteka ani program nie dostarcza takiego nagłówka.

 

Ja wpisałem void, ale kompilator mi wyalał, że main musi zwracać int'a....

A co do conio, to autor pisze w jakimś Visual C++ czy innym świństwie pod windowsa. Gdzieś mi tam przeleciało conio.h w tutorialu, więc dodałem jak mi się kompilacja sypała  :Wink: 

 *Quote:*   

> Musisz zlinkować z biblioteką matematyczną jeżeli chcesz używać funkcji sinus, dodaj -lm do opcji kompilatora. 

 

A czy jest to równoznaczne z #include <math.h> ?  :Smile: 

Generalnie kumpel mi dał wskazówkę, jak nie wiem w jakim nagłówku czegoś szukać, to przykładowo:

 *man getch wrote:*   

> SYNOPSIS
> 
>        #include <curses.h>
> 
>        int getch(void);
> ...

 

Muszę przyznać, że manual Linuksowy wymiata  :Smile: 

----------

## Arfrever

 *Yatmai wrote:*   

>  *Quote:*   Musisz zlinkować z biblioteką matematyczną jeżeli chcesz używać funkcji sinus, dodaj -lm do opcji kompilatora.  
> 
> A czy jest to równoznaczne z #include <math.h> ? 

 

Nie.

Możesz poczytać:

```
man ld
```

Perduodu linkėjimus

Arfrever

----------

## Yatmai

 *Arfrever wrote:*   

>  *Yatmai wrote:*    *Quote:*   Musisz zlinkować z biblioteką matematyczną jeżeli chcesz używać funkcji sinus, dodaj -lm do opcji kompilatora.  
> 
> A czy jest to równoznaczne z #include <math.h> ?  
> 
> Nie.

 

No faktycznie:

```
art@exunomei ~/progz $ gcc biorytm.cpp -o biorytm -lm

biorytm.cpp: In function 'double Biorytm(double, BIORYTHM)':

biorytm.cpp:15: error: 'sin' was not declared in this scope

art@exunomei ~/progz $  
```

 gdy wywalę math.h  :Wink: 

 *Quote:*   

> Albo napisać swóją funkcję getch z wykorzystaniem termiosa (jakieś 8-9 linikek).

 

A mógłbyś szepnąć coś więcej ? Bo generalnie #include <curses.h> a potem getch() powodują błąd:

```
/tmp/ccIyNcdC.o: In function `main':

string.cpp:(.text+0x1fa): undefined reference to `stdscr'

string.cpp:(.text+0x202): undefined reference to `wgetch'

collect2: ld returned 1 exit status

```

----------

## Arfrever

 *Yatmai wrote:*   

> #include <curses.h> a potem getch() powodują błąd:
> 
> ```
> /tmp/ccIyNcdC.o: In function `main':
> 
> ...

 

Musisz podczas konsolidacji dołączyć bibliotekę prawdopodobnie "libncurses.so". Jak to zrobić, jest opisane w `man ld`.

Perduodu linkėjimus

Arfrever

----------

## Yatmai

No faktycznie g++ biorytm.cpp -o biorytm -lncurses pomogło, z tym, że nie czeka na zakończenie programu, tylko od razu zwraca bash'a. Nie pomaga nawet cin.ignore()  :Sad: 

BTW. jak rozróżnić kiedy trzeba dodać -l<lib> a kiedy starczy samo #include ? Poza faktem, że mi się kompilacja sypie  :Very Happy: 

----------

## Arfrever

 *Yatmai wrote:*   

> No faktycznie g++ biorytm.cpp -o biorytm -lncurses pomogło, z tym, że nie czeka na zakończenie programu, tylko od razu zwraca bash'a. Nie pomaga nawet cin.ignore() [/code]

 

Pokaż obecny kod źródłowy.

 *Yatmai wrote:*   

> jak rozróżnić kiedy trzeba dodać -l<lib> a kiedy starczy samo #include ?

 

#include to dyrektywa preprocesora (`cpp`) dołączająca jakieś pliki nagłówkowe. Te pliki mogą jedynie deklarować jakieś funkcje bez definiowania ich. Definicje tych funkcji mogą być dostępne w postaci binarnej w ramach jakichś bibliotek dołączanych na etapie konsolidacji. Pliki wykonywalne nie mogą posiadać niezdefiniowanych odniesień, więc należy raczej zawsze używać -l<biblioteka> podczas tworzenia plików wykonywalnych używających funkcje biblioteczne. (Można pominąć -lc i ewentualnie -lstdc++ itd., gdy konsolidator `ld` nie jest wywoływany bezpośrednio, ale jest wywoływany przez `gcc`/`g++` wraz z opcjami -lc, *crt*.o i -lstdc++ w wypadku `g++`.)

Perduodu linkėjimus

Arfrever

----------

## Yatmai

```
#include <ctime>

#include <iostream>

//#include <conio.h>

#include <ctime>

#include <math.h>

#include <curses.h>

enum BIORYTHM {   BIO_PHYSICAL = 23,

      BIO_EMOTIONAL = 28,

      BIO_INTELECTUAL = 33 };

const double PI = 3.1415926538;

double Biorytm(double fDni, BIORYTHM Cykl)

{

   return 100 * sin((2 * PI / Cykl) * fDni);

}

int main()

{

   tm DataUrodzenia = { 0, 0, 0, 0, 0, 0, 0, 0 };

        tm AktualnyCzas = { 0, 0, 0, 0, 0, 0, 0, 0 };

        tm RoznicaCzasu = { 0, 0, 0, 0, 0, 0, 0, 0 };

   std::cout << "Podaj date urodzenia" << std::endl;

   std::cout << "- dzien: ";

   std::cin >> DataUrodzenia.tm_mday;

   std::cout << "- miesiac: ";

   std::cin >> DataUrodzenia.tm_mon;

   DataUrodzenia.tm_mon--;

   std::cout << "- rok: ";

   std::cin >> DataUrodzenia.tm_year;

   DataUrodzenia.tm_year -= 1900;

   time_t Czas = time(NULL);

   AktualnyCzas = *localtime(&Czas);

   RoznicaCzasu.tm_mday = AktualnyCzas.tm_mday - DataUrodzenia.tm_mday;

        RoznicaCzasu.tm_mon = AktualnyCzas.tm_mon - DataUrodzenia.tm_mon;

        RoznicaCzasu.tm_year = AktualnyCzas.tm_year - DataUrodzenia.tm_year;

   double fPrzezyteDni = RoznicaCzasu.tm_year * 365.25

            + RoznicaCzasu.tm_mon * 30.4375

            + RoznicaCzasu.tm_mday;

   

   std::cout << std::endl;

   std::cout << "Twoj biorytm" << std::endl;

   getch();

   std::cout << "- fizyczny: " << Biorytm(fPrzezyteDni, BIO_PHYSICAL) << std::endl;

   std::cout << "- emocjonalny: " << Biorytm(fPrzezyteDni, BIO_EMOTIONAL) << std::endl;

   std::cout << "- intelektualny: " << Biorytm(fPrzezyteDni, BIO_INTELECTUAL) << std::endl;

   

   std::cin.ignore();

   getch();

}
```

Żaden z getch() nie łapie - od razu leci wynik i bash.

----------

## znal

zamiast getch() użyj np. std::cin.get();

po co 2x includujesz ctime?

----------

## Yatmai

std::cin.ignore() i std:cin.get() w duecie zadziałały i nie trzeba do tego curses.h  :Smile: 

A ctime nie zauważyłem, że już jest  :Smile: 

W końcu działa jak należy i mam nadzieję, że teraz będe potrafił _poprawnie_ skompilować swoje wypociny  :Wink:  Generalnie w C++ raczej nie błyszczę, więc dzięki bardzo za cierpliwość do n00b'owskich pytań  :Smile: 

@mziab, @no4b, @Morpheouss, @znal, @Arfrever, dziękuję Wam  :Smile: 

----------

## no4b

Odpowiednik getcha, nie wymaga ncurses, jedynie #include <termios.h>

```
int myGetch(void) {

        struct termios oldTerm, newTerm;

        int chr;

        tcgetattr(STDIN_FILENO, &oldTerm);

        newTerm = oldTerm;

        newtTerm.c_lflag &= ~(ICANON | ECHO);

        tcsetattr(STDIN_FILENO, TCSANOW, &newTerm);

        chr = getchar();

        tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);

        return chr;

}

```

----------

