|
| Hvordan returnere jeg et array? Fra : Stefan Kristensen |
Dato : 25-06-02 09:26 |
|
Hejsa.
Jeg er noget rusten i mit c++:
Hvordan definerer jeg en metode, der returnerer et array?
char[] test()
{
char string[128] = "abcd";
return string;
}
giver nogle 'sjove' fejl. Hvad gør jeg forkert?
På forhånd tak
Stefan
| |
Jakob Schmidt (25-06-2002)
| Kommentar Fra : Jakob Schmidt |
Dato : 25-06-02 09:37 |
|
"Stefan Kristensen" <ks_hot@hotmail.com> writes:
> Jeg er noget rusten i mit c++:
> Hvordan definerer jeg en metode, der returnerer et array?
>
> char[] test()
> {
> char string[128] = "abcd";
> return string;
> }
Dit problem er, at du returnerer en pointer (arrays i C++ er næsten det
samme som pointers) til en automatisk variabel - altså en variabel, der
er erklæret inden i en funktion. Enten skal du erklære et globalt
array, eller også må du allokere hukommelse på hoben (automatiske
variabler havner på stakken, og det, der står der er altid midlertidigt).
Hvis du gør det, skal du også huske på, at modtagerne af returværdien fra
din funktion så har ansvaret for at deallokere hukommelsen igen - ellers
har du en lækage.
--
Jakob
| |
Stefan Kristensen (25-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 25-06-02 09:41 |
|
> Enten skal du erklære et globalt
> array
Nej tak
> eller også må du allokere hukommelse på hoben (automatiske
> variabler havner på stakken, og det, der står der er altid midlertidigt).
> Hvis du gør det, skal du også huske på, at modtagerne af returværdien fra
> din funktion så har ansvaret for at deallokere hukommelsen igen - ellers
> har du en lækage.
Hmm... Det lyder som noget jeg lærte for små otte år siden. Har du et lille
eksempel?
mvh
Stefan
| |
Jakob Schmidt (25-06-2002)
| Kommentar Fra : Jakob Schmidt |
Dato : 25-06-02 10:04 |
|
"Stefan Kristensen" <ks_hot@hotmail.com> writes:
> > Enten skal du erklære et globalt
> > array
> Nej tak
Det var godt.
> > eller også må du allokere hukommelse på hoben (automatiske
> > [snip]
> Hmm... Det lyder som noget jeg lærte for små otte år siden. Har du et lille
> eksempel?
haha, jeg har ikke selv brugt C++ længe. Men i C gør man jo bare sådan:
(utestet kodesnippet)
char *test( void ) {
char *array = malloc( 128 );
if ( !array ) /* fejl */
crashAndBurn( "Arrrrrrrrrghhhh\n" ); /* whatever */
return array;
}
og klienten siger så
char foo[] = test();
foo[ 0 ] = 'H';
foo[ 1 ] = 'e';
foo[ 2 ] = 'j'¨;
........
free( foo ); /* når du er færdig */
Ovre i C++ bruger man hellere new() og delete(), men jeg kan ikke huske, om
de også kan bruges til simple arrays og sådan noget - man bruger dem jo
typisk sammen med klasser/objeker.
--
Jakob
| |
Stefan Kristensen (25-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 25-06-02 10:10 |
|
> Det var godt.
lol
> haha, jeg har ikke selv brugt C++ længe. Men i C gør man jo bare sådan:
Det prøver jeg så bare
Mange tak
| |
Jakob Schmidt (25-06-2002)
| Kommentar Fra : Jakob Schmidt |
Dato : 25-06-02 10:13 |
|
"Stefan Kristensen" <ks_hot@hotmail.com> writes:
JS:
> > haha, jeg har ikke selv brugt C++ længe. Men i C gør man jo bare sådan:
> Det prøver jeg så bare
Hvis du vil lave rigtig C++, så check Mogens' svar.
Ellers, så fandt jeg også lige den her, hvor brugen af new og delete er
forklaret - det er tættere på rigtig C++, end malloc og free:
http://www.acm.org/crossroads/xrds1-1/ovp.html
--
Jakob
| |
Stefan Kristensen (25-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 25-06-02 10:20 |
| | |
Byrial Jensen (25-06-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 25-06-02 18:36 |
|
Jakob Schmidt <sumus@aut.dk> skrev:
> "Stefan Kristensen" <ks_hot@hotmail.com> writes:
>
>> Jeg er noget rusten i mit c++:
>> Hvordan definerer jeg en metode, der returnerer et array?
>>
>> char[] test()
>> {
>> char string[128] = "abcd";
>> return string;
>> }
>
> Dit problem er, at du returnerer en pointer (arrays i C++ er næsten det
> samme som pointers) til en automatisk variabel - altså en variabel, der
> er erklæret inden i en funktion. Enten skal du erklære et globalt
> array, eller også må du allokere hukommelse på hoben
Der er nu også en tredje mulighed. Behold en lokal variabel, men lav
den statisk i stedet for automatisk:
char *test()
{
static char string[128] = "abcd";
return string;
}
Nu vil string ikke oprettes når funktionen kaldes, og nedlægges
igen ved returneringen, men eksistere hele tiden mens programmet
kører. Til gengæld vil det altid være den samme pointer som
returneres.
| |
Bertel Lund Hansen (25-06-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 25-06-02 20:16 |
|
Byrial Jensen skrev:
>Der er nu også en tredje mulighed. Behold en lokal variabel, men lav
>den statisk i stedet for automatisk:
Svarer det så egentlig ikke til en global variabel?
--
Bertel
http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/
| |
Mogens Hansen (25-06-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 25-06-02 21:09 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk>
>
> Svarer det så egentlig ikke til en global variabel?
Bortset fra scope, og hvornår den bliver oprettet.
En lokal static variabel bliver oprettet første gang funktionen bliver
kaldt.
En global variabel bliver oprettet inden main starter.
Venlig hilsen
Mogens Hansen
| |
Byrial Jensen (27-06-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 27-06-02 16:57 |
|
Mogens Hansen <mogens_h@dk-online.dk> skrev:
> En lokal static variabel bliver oprettet første gang funktionen bliver
> kaldt.
Det er muligt at den oprettes første gang funktionen bliver kaldt,
men den kan tilsyneladende blive initialiseret ad 2 omgange hvoraf
den sidste omgang ikke nødvendigvis er ved første kald af
funktionen.
Jeg har eksperimenteret lidt med en C++-oversætter (gcc 3.1), og
så vidt jeg kan bedømme, gør den følgende:
- Hvis variablen skal initialiseres til en konstant værdi, har
den den pågældende værdi så snart funktionen er kaldt. Værdien
ændres ikke ved passage af erklæringen.
- Hvis variablen skal initialiseres til en ikke-konstant værdi,
har den værdien 0 indtil programudførelsen har passeret
erklæringen første gang. Ved første passage af erklæringen
beregnes initialiseringsværdien i erklæringen, og den tildeles
variablen.
Det illustreres af dette program:
#include <iostream>
void func(int n)
{
if (n == 1)
goto forbi;
static int k = 2;
static int v = n;
forbi:
std::cout << "func(" << n << "): k = " << k << '\n';
std::cout << "func(" << n << "): v = " << v << '\n';
}
int main()
{
func(1);
func(2);
goto forbi;
tilbage:
static int k = 2;
static int v = k * 2;
std::cout << "Erklæring passeret første gang:\n";
std::cout << "k = " << k << '\n';
std::cout << "v = " << v << '\n';
return 0;
forbi:
std::cout << "Erklæring ikke passeret:\n";
std::cout << "k = " << k << '\n';
std::cout << "v = " << v << '\n';
k = 5;
v = 5;
std::cout << "k og v sat til 5 med \"=\"-operatoren:\n";
std::cout << "k = " << k << '\n';
std::cout << "v = " << v << '\n';
goto tilbage;
}
Som giver følgende output:
func(1): k = 2
func(1): v = 0
func(2): k = 2
func(2): v = 2
Erklæring ikke passeret:
k = 2
v = 0
k og v sat til 5 med "="-operatoren:
k = 5
v = 5
Erklæring passeret første gang:
k = 5
v = 10
Er det korrekt output?
| |
Mogens Hansen (04-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 04-07-02 18:14 |
|
"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrnahmdk1.10t.bjensen@ask.ask...
> Mogens Hansen <mogens_h@dk-online.dk> skrev:
>
> > En lokal static variabel bliver oprettet første gang funktionen bliver
> > kaldt.
>
> Det er muligt at den oprettes første gang funktionen bliver kaldt,
> men den kan tilsyneladende blive initialiseret ad 2 omgange hvoraf
> den sidste omgang ikke nødvendigvis er ved første kald af
> funktionen.
[snip]
> void func(int n)
> {
> if (n == 1)
> goto forbi;
>
> static int k = 2;
> static int v = n;
>
> forbi:
>
Det er ulovlig i C++ at hoppe over erklæringer med initialisering (§6.7-3)
[snip]
> Er det korrekt output?
Programmet burde ikke kunne oversætte - og gør det heller ikke med
- Microsoft Visual C++ V6.0
- Borland C++Builder V5.0
- Borland C++Builder V6.0
(men oversætter dog med
- Microsoft Visual C++ V7.0 (.NET)
- Comeau 4.3.0
- Intel C++ V5.0
- Intel C++ V6.0
)
Venlig hilsen
Mogens Hansen
| |
Byrial Jensen (04-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 04-07-02 20:03 |
|
Mogens Hansen <mogens_h@dk-online.dk> skrev:
> Det er ulovlig i C++ at hoppe over erklæringer med initialisering (§6.7-3)
Interessant. Det er så endnu et eksempel på at korrekte C-programmer
ikke altid også er korrekte C++-programmer. Tak for oplysningen.
I C må man ikke hoppe ind i scopet for en variabel med modificerbar
type[1] (hverken forfra eller bagfra), men bortset fra det må man
gerne hoppe over initialiseringer.
[1] Dvs. en type som er eller indeholder et array med variabel
længde.
| |
Igor V. Rafienko (04-07-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 04-07-02 20:13 |
|
[ Byrial Jensen ]
[ snip ]
> I C må man ikke hoppe ind i scopet for en variabel med modificerbar
> type[1] (hverken forfra eller bagfra), men bortset fra det må man
> gerne hoppe over initialiseringer.
Ehh... hva er verdien av de variablene som skulle ha vært initialisert
da? (eller sier standarden (C99, antageligvis) at innholdet er
unspecified?)
ivr
--
C++: "an octopus made by nailing extra legs onto a dog"
-- Steve Taylor, 1998
| |
Byrial Jensen (04-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 04-07-02 22:07 |
|
Igor V. Rafienko <igorr@ifi.uio.no> skrev:
> [ Byrial Jensen ]
>
>> I C må man ikke hoppe ind i scopet for en variabel med modificerbar
>> type[1] (hverken forfra eller bagfra), men bortset fra det må man
>> gerne hoppe over initialiseringer.
>
> Ehh... hva er verdien av de variablene som skulle ha vært initialisert
> da? (eller sier standarden (C99, antageligvis) at innholdet er
> unspecified?)
Statiske variable initialiseres i C før programudførelsen begynder,
så de har deres initialiserede værdi indtil den måtte blive ændret,
uanset om initialiseringskoden er passeret eller ej.
Automatiske variable intialiseres hver gang programudførelsen
passerer initialiseringen. (Hvis en erklæring uden initalisering
passeres, bliver en evt. værdi gjort ubestemt). Hvis der hverken er
udført initialisering eller tildeling (assignment) til variablen,
er værdien ubestemt. Det er udefineret adfærd at forsøge at læse en
ubestemt værdi.
Se C99, afsnit 6.2.4#3, 6.2.4#5 og 6.8#3.
| |
Anders Wegge Jakobse~ (04-07-2002)
| Kommentar Fra : Anders Wegge Jakobse~ |
Dato : 04-07-02 20:33 |
|
"Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
> Mogens Hansen <mogens_h@dk-online.dk> skrev:
>> Det er ulovlig i C++ at hoppe over erklæringer med initialisering (§6.7-3)
> Interessant. Det er så endnu et eksempel på at korrekte C-programmer
> ikke altid også er korrekte C++-programmer. Tak for oplysningen.
Det er ikke et gyldigt C-program (eller et fragment af samme) som TOP
har bragt...
> I C må man ikke hoppe ind i scopet for en variabel med modificerbar
> type[1] (hverken forfra eller bagfra), men bortset fra det må man
> gerne hoppe over initialiseringer.
... idet der er statements før variabel erklæringerne.
--
/Wegge
| |
Byrial Jensen (04-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 04-07-02 22:07 |
|
Anders Wegge Jakobsen <wegge@wegge.dk> skrev:
>"Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
>
> > Interessant. Det er så endnu et eksempel på at korrekte C-programmer
> > ikke altid også er korrekte C++-programmer. Tak for oplysningen.
>
> Det er ikke et gyldigt C-program (eller et fragment af samme) som TOP
> har bragt...
Hvad er TOP?
Det program jeg skrev tidligere i tråden, var klart et forsøg på at
lave et C++-program med brug af sprogelementer som ikke findes i C
(<iostream>, std::cout og statiske variable med ikke-konstant
initialisering), men det kan nemt konverteres til et korrekt
C-program med hop over initialiseringer.
> > I C må man ikke hoppe ind i scopet for en variabel med modificerbar
> > type[1] (hverken forfra eller bagfra), men bortset fra det må man
> > gerne hoppe over initialiseringer.
>
> ... idet der er statements før variabel erklæringerne.
Øh, og hvad er din pointe med det?
| |
Anders Wegge Jakobse~ (05-07-2002)
| Kommentar Fra : Anders Wegge Jakobse~ |
Dato : 05-07-02 12:36 |
|
"Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
> Anders Wegge Jakobsen <wegge@wegge.dk> skrev:
>> "Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
>>
>> > Interessant. Det er så endnu et eksempel på at korrekte C-programmer
>> > ikke altid også er korrekte C++-programmer. Tak for oplysningen.
>>
>> Det er ikke et gyldigt C-program (eller et fragment af samme) som TOP
>> har bragt...
> Hvad er TOP?
The Other Poster. Jeg har skrevet for meget engelsk i går.
> Det program jeg skrev tidligere i tråden, var klart et forsøg på at
> lave et C++-program med brug af sprogelementer som ikke findes i C
> (<iostream>, std::cout og statiske variable med ikke-konstant
> initialisering), men det kan nemt konverteres til et korrekt
> C-program med hop over initialiseringer.
>> > I C må man ikke hoppe ind i scopet for en variabel med modificerbar
>> > type[1] (hverken forfra eller bagfra), men bortset fra det må man
>> > gerne hoppe over initialiseringer.
>>
>> ... idet der er statements før variabel erklæringerne.
> Øh, og hvad er din pointe med det?
Det er en syntax fejl i C, hvorfor din kommentar om at korrekte
C-programmer ikke altid er korrekte C++-programmer ikke er relevant i
dette tilfælde.
--
/Wegge
| |
Byrial Jensen (05-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 05-07-02 15:32 |
|
Anders Wegge Jakobsen <wegge@wegge.dk> skrev:
>"Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
> > Anders Wegge Jakobsen <wegge@wegge.dk> skrev:
> >> "Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
> >>
> >> > Interessant. Det er så endnu et eksempel på at korrekte C-programmer
> >> > ikke altid også er korrekte C++-programmer. Tak for oplysningen.
> >>
> >> Det er ikke et gyldigt C-program (eller et fragment af samme) som TOP
> >> har bragt...
>
> >> ... idet der er statements før variabel erklæringerne.
>
> > Øh, og hvad er din pointe med det?
>
> Det er en syntax fejl i C, hvorfor din kommentar om at korrekte
> C-programmer ikke altid er korrekte C++-programmer ikke er relevant i
> dette tilfælde.
For det første er det tilladt i C99 frit at blande sætninger og
erklæringer, så koden var på det punkt korrekt C-kode.
For det andet kan det nemt omskrives til korrekt C89-kode (ANSI C)
ved et indsætte nogle ekstra blokke. Nedenstående er f.eks. et helt
korrekt C89-program:
#include <stdio.h>
int main ()
{
goto forbi;
{
static int var = 25;
forbi:
printf ("var er %d\n", var);
}
return 0;
}
| |
Anders Wegge Jakobse~ (05-07-2002)
| Kommentar Fra : Anders Wegge Jakobse~ |
Dato : 05-07-02 16:32 |
|
"Byrial" == Byrial Jensen <bjensen@nospam.dk> writes:
...
> For det første er det tilladt i C99 frit at blande sætninger og
> erklæringer, så koden var på det punkt korrekt C-kode.
I stand corrected.
--
/Wegge
| |
J. Martin Petersen (25-06-2002)
| Kommentar Fra : J. Martin Petersen |
Dato : 25-06-02 20:42 |
|
Bertel Lund Hansen <nospam@lundhansen.dk> writes:
> Byrial Jensen skrev:
>
> >Der er nu også en tredje mulighed. Behold en lokal variabel, men lav
> >den statisk i stedet for automatisk:
>
> Svarer det så egentlig ikke til en global variabel?
Nej, de er ikke i det globale navnerum, jvf. følgende:
"Internal static variables are local to a particular function just as
automatic variables are, but unlike automatics, they remain in
existance rather than coming and going each time the function is
activated. This means that internal static variables provide private,
permanent storage within a single function."
Kernighan & Ritchie, The C Programming Language, 2nd ed. side 83.
--
J. Martin Petersen "Atter springer gnuerne ud i vandet..."
| |
Byrial Jensen (25-06-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 25-06-02 22:09 |
|
Bertel Lund Hansen <nospam@lundhansen.dk> skrev:
> Byrial Jensen skrev:
>
>>Der er nu også en tredje mulighed. Behold en lokal variabel, men lav
>>den statisk i stedet for automatisk:
>
> Svarer det så egentlig ikke til en global variabel?
Det kommer an på hvad du mener med "svarer til", og hvad man i det
hele taget mener med lokale og globale variabler.
Jeg kalder variable som er erklæret i en funktion, for lokale.
Deres scope er fra erklæringen til afslutningen af den blok som
erklæringen er i.
Variable erklæret uden for en funktion kalder jeg globale. Deres
scope er fra erklæringen til enden af oversættelsesenheden.
Uafhængigt heraf kan variabler og andre objekter deles i 3 grupper
efter varighed:
- statiske objekter findes under hele programudførelsen
- automatiske objekter findes fra erklæring og til den blok hvori
erklæringen findes, forlades. (Dog for arrays med variabel
længde indtil objektets scope forlades).
- allokerede objekter findes fra allokering til deallokering.
Globale variable er altid statiske.
Lokale variable er statiske hvis de erklæres til at være det med
"static" eller "extern", og ellers automatiske.
Så en statisk lokal variabel har varigheden til fælles med globale
variable.
| |
Jakob Schmidt (26-06-2002)
| Kommentar Fra : Jakob Schmidt |
Dato : 26-06-02 07:25 |
|
Byrial Jensen <bjensen@nospam.dk> writes:
> - automatiske objekter findes fra erklæring og til den blok hvori
> erklæringen findes, forlades. (Dog for arrays med variabel
> længde indtil objektets scope forlades).
Jeg vil gerne lige være med på, hvad du mener med parentesen. Gider du
uddybe?
--
Jakob
| |
Byrial Jensen (26-06-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 26-06-02 21:33 |
|
Jakob Schmidt <sumus@aut.dk> skrev:
> Byrial Jensen <bjensen@nospam.dk> writes:
>
>> - automatiske objekter findes fra erklæring og til den blok hvori
>> erklæringen findes, forlades. (Dog for arrays med variabel
>> længde indtil objektets scope forlades).
>
> Jeg vil gerne lige være med på, hvad du mener med parentesen. Gider du
> uddybe?
Nedenstående program skulle illustrere det.
#include <stdio.h>
void fast_array_fun(void)
{
int *ip = 0;
tilbage:
if (ip)
{
/* Når dette kode udføres, peger ip på et automatisk objekt (arr).
Vi er uden for objektets scope, men objektet findes stadig
fordi blokken som det er erklæret i, ikke er forladt endnu.
Derfor må det gerne tilgås gennem ip. */
printf ("arr[0] = %d\n", *ip); /* Dette et o.k. */
return;
}
int arr[5];
arr[0] = 27;
ip = &arr[0];
goto tilbage;
}
void var_array_fun(int len)
{
int *ip = 0;
tilbage:
if (ip)
{
/* Når dette kode udføres, peger ip på et automatisk objekt (arr)
som er et array med variabel længde. Sådanne objekter lever
kun indtil programudførslen forlader objektets scope, og det
er sket her. Derfor er det udefineret adfærd at dereferere ip
her. */
printf ("arr[0] = %d\n", *ip); /* Advarsel: Udefineret adfærd! */
return;
}
int arr[len];
arr[0] = 27;
ip = &arr[0];
goto tilbage;
}
int main()
{
fast_array_fun();
var_array_fun(5);
return 0;
}
| |
Mogens Hansen (25-06-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 25-06-02 21:09 |
|
"Byrial Jensen" <bjensen@nospam.dk> wrote
[snip]
> Nu vil string ikke oprettes når funktionen kaldes...
Jo, netop _første_ gang funktionen bliver kaldt.
Venlig hilsen
Mogens Hansen
| |
Byrial Jensen (25-06-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 25-06-02 22:53 |
|
Mogens Hansen <mogens_h@dk-online.dk> skrev:
> "Byrial Jensen" <bjensen@nospam.dk> wrote
>
> [snip]
>> Nu vil string ikke oprettes når funktionen kaldes...
>
> Jo, netop _første_ gang funktionen bliver kaldt.
Nej, den oprettes før programudførelsen påbegyndes ifølge afsnit
6.2.4#3 i C99. Jeg skal dog ikke kunne afvise at C++ gør
anderledes.
Det gør dog ingen forskel i praksis da man ikke kan komme til at
bruge variablen før funktionen bliver kaldt første gang.
| |
Anders J. Munch (26-06-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 26-06-02 22:13 |
|
"Byrial Jensen" <bjensen@nospam.dk> skrev i en meddelelse
news:slrnahho31.1u8.bjensen@ask.ask...
> Mogens Hansen <mogens_h@dk-online.dk> skrev:
> > "Byrial Jensen" <bjensen@nospam.dk> wrote
> >
> > [snip]
> >> Nu vil string ikke oprettes når funktionen kaldes...
> >
> > Jo, netop _første_ gang funktionen bliver kaldt.
>
> Nej, den oprettes før programudførelsen påbegyndes ifølge afsnit
> 6.2.4#3 i C99. Jeg skal dog ikke kunne afvise at C++ gør
> anderledes.
Initialiseringer i C++ kan udføre arbitrær kode, så man kan næppe tale
om at det sker før programudførslen - selv om det sker før main.
I C++ sker initialiseringen i to gennemløb: først de simple
initialiseringer[1], som kan implementeres effektivt ved at placere
variablerne i et initialiseret segment, og dernæst de øvrige
initialiseringer, der potentielt har behov for at udføre kode.
>
> Det gør dog ingen forskel i praksis da man ikke kan komme til at
> bruge variablen før funktionen bliver kaldt første gang.
I C++ derimod gør det en forskel; initialiseringen sker først når
funktionen bliver kaldt første gang. Dette implementeres som regel ved
at compileren generer noget elendigt ikke-reentrant kode med et skjult
allerede-initialiseret flag.
Hvordan har C det forresten med initialisering der kalder kode? Er
foo_t foo = skaf_foo();
efterhånden blevet lovligt i globalt scope?
mvh.
Anders
[1] Af typen POD = konstant.
--
Anders Munch, softwareudvikler
Stadig forvirret men på et højere niveau. Fjern fra min emailadresse.
| |
Byrial Jensen (26-06-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 26-06-02 23:02 |
|
Anders J. Munch <andersjm@inbound.dk> skrev:
> I C++ derimod gør det en forskel; initialiseringen sker først når
> funktionen bliver kaldt første gang. Dette implementeres som regel ved
> at compileren generer noget elendigt ikke-reentrant kode med et skjult
> allerede-initialiseret flag.
Hmm? Det lyder temmelig upraktisk i forbindelse med flertrådede
programmer.
Er koden herunder korrekt C++-kode?
Hvis ja, hvad er så værdierne af a og b på de angivne steder?
int func(void) // Dette skal forestille C++-kode
{
static int a = 5;
// Hvad er værdien af a her? 5 eller 6?
a = 10;
{
static int b = a++;
// Hvad er værdien af b her? 5 eller 10?
// Hvad er værdien af a her? 10 eller 11?
// ...
}
// ...
}
> Hvordan har C det forresten med initialisering der kalder kode? Er
> foo_t foo = skaf_foo();
> efterhånden blevet lovligt i globalt scope?
Nej.
Automatiske variable i funktioner må initialiseres med vilkårlig
kode; der er ingen reel forskel på initialisering af sådanne
variable og en erklæring uden initialisering efterfulgt af
assignment til variablen.
Globale variable og statiske lokale variable må derimod kun
initialiseres med konstant-udtryk som kan beregnes på
oversættelsestidspunktet.
| |
Anders J. Munch (27-06-2002)
| Kommentar Fra : Anders J. Munch |
Dato : 27-06-02 18:32 |
|
"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrnahkeh7.b7l.bjensen@ask.ask...
> Anders J. Munch <andersjm@inbound.dk> skrev:
> > I C++ derimod gør det en forskel; initialiseringen sker først når
> > funktionen bliver kaldt første gang. Dette implementeres som regel ved
> > at compileren generer noget elendigt ikke-reentrant kode med et skjult
> > allerede-initialiseret flag.
>
> Hmm? Det lyder temmelig upraktisk i forbindelse med flertrådede
> programmer.
Præcist. Singleton initialisering er en hel videnskab af samme grund.
> Er koden herunder korrekt C++-kode?
> Hvis ja, hvad er så værdierne af a og b på de angivne steder?
>
> int func(void) // Dette skal forestille C++-kode
> {
> static int a = 5;
>
> // Hvad er værdien af a her? 5 eller 6?
a = 5.
> a = 10;
>
> {
> static int b = a++;
> // Hvad er værdien af b her? 5 eller 10?
> // Hvad er værdien af a her? 10 eller 11?
Det med de to gennemløb gælder kun for variabler i globalt scope.
Funktions-lokale statics er lidt enklere. De initialiseres blot første gang
koden når til det punkt. Derfor: b = 10, a = 11.
> > Hvordan har C det forresten med initialisering der kalder kode? Er
> > foo_t foo = skaf_foo();
> > efterhånden blevet lovligt i globalt scope?
>
> Nej.
Takker for oplysningen.
- Anders
| |
Jens Axel Søgaard (27-06-2002)
| Kommentar Fra : Jens Axel Søgaard |
Dato : 27-06-02 12:56 |
|
Anders J. Munch wrote:
> "Byrial Jensen" <bjensen@nospam.dk> skrev i en meddelelse
>> Nej, den oprettes før programudførelsen påbegyndes
>> ifølge afsnit 6.2.4#3 i C99. Jeg skal dog ikke kunne
>> afvise at C++ gør anderledes.
>
> Initialiseringer i C++ kan udføre arbitrær kode, så man
> kan næppe tale om at det sker før programudførslen - selv
> om det sker før main.
Der er ikke noget i vejen for at
- reservering af selve pladsen
- initialisering af indholdet af pladsen
er adskilte i tid.
Dermed kan reservering godt foregå før programudførslen,
selvom den tilhørende initialisering først sker senere.
--
Jens Axel Søgaard
| |
Mogens Hansen (25-06-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 25-06-02 10:08 |
|
"Stefan Kristensen" <ks_hot@hotmail.com> wrote
> Jeg er noget rusten i mit c++:
> Hvordan definerer jeg en metode, der returnerer et array?
>
> char[] test()
> {
> char string[128] = "abcd";
> return string;
> }
>
> giver nogle 'sjove' fejl. Hvad gør jeg forkert?
Din variabel "string" lever kun så længe "test" kører - det giver derfor
ikke nogen mening at returnere den.
Det nemme svar er: lad være, og brug C++ Standard library i stedet:
#include <string>
std::string test()
{
std::string txt("abcd");
return txt;
}
Her returnerer du en _kopi_ af "txt".
Du har således ingen problemer med levetiden, eller mulighed for memory
leaks.
Hvis det virkeligt er et array, og ikke en tekst-streng, du har brug for at
returnere så brug std::vector i stedet for std::string.
Venlig hilsen
Mogens Hansen
| |
Stefan Kristensen (25-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 25-06-02 10:10 |
|
Tak for foklaringen og den alternative løsning
Stefan
| |
Stefan Kristensen (27-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 27-06-02 08:32 |
|
> #include <string>
>
> std::string test()
> {
> std::string txt("abcd");
> return txt;
> }
>
Øhh... Hvordan skriver jeg så en std::string ud? printf("%s", test()); giver
en 'memory could not be read' fejl
Stefan
| |
J. Martin Petersen (27-06-2002)
| Kommentar Fra : J. Martin Petersen |
Dato : 27-06-02 08:42 |
|
"Stefan Kristensen" <stk@rus.dk> writes:
> > #include <string>
> >
> > std::string test()
> > {
> > std::string txt("abcd");
> > return txt;
> > }
> >
> Øhh... Hvordan skriver jeg så en std::string ud? printf("%s", test()); giver
> en 'memory could not be read' fejl
#include <iostream>
std::cout << txt;
--
J. Martin Petersen "Atter springer gnuerne ud i vandet..."
| |
Stefan Kristensen (27-06-2002)
| Kommentar Fra : Stefan Kristensen |
Dato : 27-06-02 09:08 |
|
mange tak
stefan
| |
|
|