/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
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

> 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
Added to Favorites...



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



Søg
Reklame
Statistik
Spørgsmål : 177496
Tips : 31968
Nyheder : 719565
Indlæg : 6408491
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste