On Tue, Aug 26, 2003 at 01:50:40PM +0300, Dorin Lazar wrote:
> On Tuesday 26 August 2003 10:39, Serghei Amelian wrote:
> > Hmm, de ce conteaza? Din cate stiu eu "return buffer" este sinonim cu
> > "return &buffer[0]", asa ca unde e problema? Poti sa-mi dai un exemplu unde
> > ar avea importanta chestia asta?
Da, return buffer si return &buffer[0] sunt identice.
> Diferenta este locul unde se aloca memoria. char buffer[512] o sa il ai
> alocat pe stiva, sau static (daca e in afara contextului vreunei functii.
Sau static daca pui static in fata declaratiei, in contextul unei functii.
> Daca ai intr-o functie:
> const char *func(void)
> {
> char buffer[1023];
> return buffer;
> }
>
> Asta e un dezastru waiting to happen. (dar stiai asta, nu?)
Corect. Dar daca te uiti atent la codul lui, vei observa ca el are
"static" in fata buffer-ului, ceea ce inseamna ca spatiul pentru
variabila respectiva va fi alocat in segmentul de date.
> Cand trimiti ca parametru la o functie care primeste un char * ca parametru
> atunci se face cast-ul automat, daca primeste un char[] ca parametru se
> copiaza pe stiva (cred).
GRESIT!
Nu exista NICI O diferenta din punctul de vedere al unui compilator de C
standard intre prototipurile:
int main(int argc, char **argv);
int main(int argc, char *argv[]);
sau intre
void a(int *b);
void a(int b[]);
(hint: incearca gcc -S fisier.c si vezi ce cod assembler genereaza cu
fiecare din cele doua modalitati de declarare)
In plus, urmatorul program se compileaza fara probleme chiar cu:
gcc -Wall -W -Werror -Wstrict-prototypes -ansi -pedantic
/* start */
#include <stdio.h>
int main(int argc, char **argv);
int main(int argc, char *argv[])
{
int i;
for (i = 0; i < argc; i++)
printf("%s\n", argv[i]);
return 0;
}
/* end */
A se observa diferenta intre linia 3 (prototipul lui main) si linia 5,
implementarea.
MAI MULT: Daca pe linia cu printf schimb argv[i] in i[argv], nu se
intampla nimic grav. Si codul assembler generat este identic.
De ce? Fiindca din punctul de vedere al limbajului C, un array fara
dimensiune declarata este acelasi lucru cu un pointer. Ba mai mult,
compilatorul traduce intern referintele de genul "a[i]" in "*(a+i)",
motiv pentru care poti la fel de bine sa folosesti "i[a]" sau "a[i]"
pentru acelasi rezultat. Am comparat mai multe variante tot cu gcc -S,
dar am adaugat si o optiune de optimizare, -O. Pentru array de intregi
codul assembler era identic, pentru double a devenit identic dupa
adaugarea optiunii -O. Culmea, mie mi s-a parut ceva mai ineficienta
metoda folosita pentru scrierea "a[i]" daca nu folosesti optimizari.
> Daca functia in schimb returneaza un char[] atunci la retur se va face
> copierea intregului string (1023 de caractere).
De cand are un string 1023 de caractere? Vrei sa vezi
stringuri de 10M? Uite unul aici:
/* start */
#include <stdio.h>
#define MAX (1024*1024*10)
int main(void)
{
int i;
char a[MAX];
for (i = 0; i < MAX; i++)
a[i] = (i % 26) + 'A';
a[MAX - 1] = '\0';
printf("%s", a);
return 0;
}
/* end */
> At least, that's the way I see it.
Cumpara-ti ochelari. Sau o carte de C.
> Dorin.
Alex
(Obosit, plictisit)
------------+-------------------------------------------------------
Alex Popa, | "Computer science is no more about computers than
[EMAIL PROTECTED]| astronomy is about telescopes" -- E. W. Dijkstra
------------+-------------------------------------------------------
---
Detalii despre listele noastre de mail: http://www.lug.ro/