konto usunięte
Temat: Rynek IT z C C++
Piotr Pszczolkowski:
No to w takim razie wyrazenia regularne sa czescia C i tym samym C++ od
zawsze. Patrz regexp.h
Nie, bo regexp.h nie nalezy do biblioteki standardowej jezyka o ktorej wspominal Maciej.
konto usunięte
Piotr Pszczolkowski:
No to w takim razie wyrazenia regularne sa czescia C i tym samym C++ od
zawsze. Patrz regexp.h
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Piotr Likus:
Co do NULL:
Do niedawna nie wiedziałem, że NULL to takie wielkie halo.
Ale ponoć dopiero nullptr ma być wskaźnikiem "do niczego" a NULL często jest definiowany jako zero(int):
#define NULL 0
tak więc może to i zgodnie ze wskaźnikami, ale na pewno nie z referencjami.
Referencje są dla mnie lepsze, bo wymuszają lepszą semantykę zarządzania pamięcią (samo się gdzieś tam zwalnia). W przypadku wskaźników nigdy nie wiadomo.
konto usunięte
Mateusz Berezecki no fluff, just stuff
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Tomasz Krzos:
Szymon Kubisiak:
Jasne, tylko złośliwy idiota podaje NULLa do funkcji przyjmującej referencje.
void f(int &i)
{
}
int main()
{
f(NULL);
return 0;
}
Taki kod u mnie w ogole sie nie kompiluje(VC++ 2003 Std). Mam wiec watpliwosci czy wg. standardu mozna przekazac NULLa do funkcji przyjmujacej referencje. Bede musial kiedys o tym poczytac.
Sam fakt, ze ktos przekazuje adres do funkcji nie oznacza, ze chce cos modyfikowac, wiec dalej nie bedziesz wiedzial co dzieje sie w przypadku drugiej konstrukcji.
konto usunięte
Szymon Kubisiak:
Ech...
To co napisałeś nie ma prawa się skompilować.
(Chociaż zadziałało by z const ref)
Jak podać NULLa do referencji? A tak:
f( *((int*)NULL) );
void f(int* i)
{
if (i == NULL)
*i = 0;
}
int main()
{
f((int*)1);
return 0;
}
Na marginesie dobra rada: z własnego doświadczenia wiem że nie należy myśleć o pointerach jako o "wskaźniku na typ":
int *piCostam;// źle
Myślcie jako o "typie 'wskaźnik na'"
int* piCostam;// dobrze
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Tomasz Krzos:
Nie podajesz NULLa(zerowego adresu). Podajesz adres, ktory jest pod adresem zerowym.
Co wiecej: biorac pod uwage powyzszy przyklad, mozna wyjsc z zalozenia, ze wkazniki to jeszcze wieksze zlo. Jezeli mam sie bawic w rzutowania, to rownie dobrze moge napsiac:
void f(int* i)
{
if (i == NULL)
*i = 0;
}
int main()
{
f((int*)1);
return 0;
}
Efekt bedzie podobny. Roznica polega na tym, ze mniej sie napisze w drugim przypadku. Innymi slowy: jak ktos bedzie chcial na sile wszystko zepsuc, to i tak zepsuje i wskaznik Cie tu nie uratuje - wrecz przeciwnie.
konto usunięte
Szymon Kubisiak:
"Adres pod adresem zerowym" ?
Referencja JEST adresem.
Teraz to już naciągasz i wcale nie jesteś zabawny.
Napisałem przykład jednolinijkowy jako czysto teoretyczną możliwość.
kodzie i jest znacznie bardziej realny (choć również ewidentnym bugiem).
To co Ty piszesz, się nie wywali, więc w czym problem? : )
Ale teraz wkraczamy na obszar "jak wywalić program" i nie jest to ograniczone do wskaźników.
Wskaźnik możesz sprawdzić, referencję nie
Piotr P. Software Developer
Piotr Likus:
Dla mnie to jazda - null powinien być nullem a nie int'em.
Piotr P. Software Developer
Szymon Kubisiak:
Na marginesie dobra rada: z własnego doświadczenia wiem że nie należy myśleć o pointerach jako o "wskaźniku na typ":
int *piCostam;// źle
Piotr P. Software Developer
Tomasz Krzos:
Szymon Kubisiak:
"Adres pod adresem zerowym" ?
Dokladnie tak. Do funkcji przekazywany jest adres, bo jak sam napisales referencja jest adresem. A wiec:
1) Masz NULLa - czyli wartosc 0.
Chodzilo mi o to, ze wskazniki nie poprawiaja bezpieczenstwa.
konto usunięte
Piotr P.:
Na jakiej platformie?
Implementacja NULL'a jest jak przepis polskiego prawa. Jego interpretacja zależy od lokalnego systemu.
NULL jest po prostu pustym wskaźnikiem. Zakładanie że NULL będzie zerem w przypadku języka C jest strzałem we własna stopę.
Ale są fundamentem języka C. Jeśli to dla Ciebie niebezpieczne, nie pisz w C ;)
konto usunięte
Piotr P.:
A od kiedy NULL jest int'em?
std::cout << typeid(NULL).name() << std::endl;
char *my_string = NULL;
Jak to sobie wyobrażasz na platformie 32 i 64 bitowej?
Piotr P. Software Developer
Tomasz Krzos:
std::cout << typeid(NULL).name() << std::endl;
Powyzszy kod wypisze... int :) Przynajmniej pod VS 2k5.
char *my_string = NULL;
Jak to sobie wyobrażasz na platformie 32 i 64 bitowej?
Nie rozumiem co chciales przez powyzszy kod pokazac :)
konto usunięte
Piotr P.:
Tomasz Krzos:
Szymon Kubisiak:
"Adres pod adresem zerowym" ?
Dokladnie tak. Do funkcji przekazywany jest adres, bo jak sam napisales referencja jest adresem. A wiec:
1) Masz NULLa - czyli wartosc 0.
Na jakiej platformie?
Implementacja NULL'a jest jak przepis polskiego prawa. Jego interpretacja zależy od lokalnego systemu.
NULL jest po prostu pustym wskaźnikiem. Zakładanie że NULL będzie zerem w przypadku języka C jest strzałem we własna stopę.
Chodzilo mi o to, ze wskazniki nie poprawiaja bezpieczenstwa.
Ale są fundamentem języka C. Jeśli to dla Ciebie niebezpieczne, nie pisz w C ;)
Piotr P. Software Developer
Tomasz Krzos:
Piotr P.:
Na jakiej platformie?
Implementacja NULL'a jest jak przepis polskiego prawa. Jego interpretacja zależy od lokalnego systemu.
Sam dokladnie nie wiem co na to standard.
Piotr P. Software Developer
Piotr Likus:
Chodzilo mi o to, ze wskazniki nie poprawiaja bezpieczenstwa.
Ale są fundamentem języka C. Jeśli to dla Ciebie niebezpieczne, nie pisz w C ;)
Wskaźniki są patogenne. Dlatego wymyślono referencje.
Dostałem wskaźnik i co dalej? Hmm, zwolnić czy nie...
Przy referencji nie ma tego wyboru.
A co do mojego NULLa to miałem na myśli to że w C++ zamiast niego stosuje się zero (0). I to jest chore. Co do wartości makra NULL to dla mnie ona może być dowolna (np. 0xfefe).
konto usunięte
Piotr P.:
Aj. Znam ludzi którzy piszą 0 zamiast FALSE i 1 zamiast TRUE.
Chore, fakt :)
<0 - error
0 - success
>0 - warning
if (!status) printf("super!");
Szymon
Kubisiak
Developer aplikacji
mobilnych Android
Tomasz Krzos:
Szymon Kubisiak:
"Adres pod adresem zerowym" ?
Dokladnie tak. Do funkcji przekazywany jest adres, bo jak sam napisales referencja jest adresem. A wiec:
1) Masz NULLa - czyli wartosc 0.
2) Za pomoca wyrazenia *((int*)NULL) odwolujesz sie do wartosci, ktora jest zapisana w komorce pamieci o adresie zero.
3) Powyzsza wartosc przekazujesz do funkcji. Wartosc ta jest(nie liczac cudow) wartoscia rozna od zera, a wiec rozna od NULLa. Nie przekazujesz wiec NULLa.
Wskaźnik możesz sprawdzić, referencję nie
Plus dla referencji ;)
Mateusz Berezecki no fluff, just stuff
#include <iostream>
extern "C" void ref_fun(int& a)
{
}
extern "C" void ptr_fun(int *a)
{
}
int main()
{
int a = 5;
ref_fun(a);
ptr_fun(&a);
}
extern "C"by kod maszynowy nie mial nazw funkcji podawanych w standardzie C++ (wiec to nie zadne szarlatanstwo - ubezpieczam sie na przyszlosc)
main:
.LFB1430:
pushq %rbp
.LCFI4:
movq %rsp, %rbp
.LCFI5:
subq $16, %rsp
.LCFI6:
movl $5, -4(%rbp)
leaq -4(%rbp), %rdi
call ref_fun
leaq -4(%rbp), %rdi
call ptr_fun
movl $0, %eax
leave
ret
An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant
Następna dyskusja: