|
| Defineret opførelse? Fra : Klaus Petersen |
Dato : 30-07-03 09:29 |
|
Hej NG.
Kan man forvente at dette program opfører sig ens med alle compilere?
unsigned int a = 10;
while (a)
printf ("%u = %u\n", a, --a );
Klaus.
| |
Anders J. Munch (30-07-2003)
| Kommentar Fra : Anders J. Munch |
Dato : 30-07-03 09:44 |
|
"Klaus Petersen" <ng@spectual.ra.bnaa.dk> wrote:
> Hej NG.
>
> Kan man forvente at dette program opfører sig ens med alle compilere?
>
> unsigned int a = 10;
>
> while (a)
> printf ("%u = %u\n", a, --a );
Nej. Der er ikke nogen påkrævet evalueringsrækkefølge for argumenter.
mvh. Anders
| |
Klaus Petersen (30-07-2003)
| Kommentar Fra : Klaus Petersen |
Dato : 30-07-03 10:16 |
|
> Nej. Der er ikke nogen påkrævet evalueringsrækkefølge for argumenter.
Takker.
| |
Soeren Sandmann (30-07-2003)
| Kommentar Fra : Soeren Sandmann |
Dato : 30-07-03 15:23 |
|
"Anders J. Munch" <andersjm@dancontrol.dk> writes:
> > unsigned int a = 10;
> >
> > while (a)
> > printf ("%u = %u\n", a, --a );
>
> Nej. Der er ikke nogen påkrævet evalueringsrækkefølge for
> argumenter.
Faktisk er det ikke engang påkrævet at der _er_ en
evalueringsrækkefølge. Det er ikke veldefineret hvad det ovenstående
gør, så resultatet kan fx være en uendelig løkke eller mærkeligere.
| |
Mogens Hansen (30-07-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 30-07-03 17:28 |
|
"Soeren Sandmann" <sandmann@daimi.au.dk> wrote
[8<8<8<]
> Faktisk er det ikke engang påkrævet at der _er_ en
> evalueringsrækkefølge. Det er ikke veldefineret hvad det ovenstående
> gør, så resultatet kan fx være en uendelig løkke eller mærkeligere.
Hvorfra har du den opfattelse ?
Jeg vil klart mene at "a" bliver talt een ned per gennemløb, og dermed kører
løkken et veldefineret antal gange.
Venlig hilsen
Mogens Hansen
| |
Bertel Brander (30-07-2003)
| Kommentar Fra : Bertel Brander |
Dato : 30-07-03 18:49 |
|
Mogens Hansen wrote:
> "Soeren Sandmann" <sandmann@daimi.au.dk> wrote
>
> [8<8<8<]
>
>>Faktisk er det ikke engang påkrævet at der _er_ en
>>evalueringsrækkefølge. Det er ikke veldefineret hvad det ovenstående
>>gør, så resultatet kan fx være en uendelig løkke eller mærkeligere.
>
>
> Hvorfra har du den opfattelse ?
>
> Jeg vil klart mene at "a" bliver talt een ned per gennemløb, og dermed kører
> løkken et veldefineret antal gange.
>
Da det er udefineret hvad der printes med printf, har programmet
udefineret opførsel. C-standarden sætter ingen begrænsninger for hvad
et program der har udefineret opførsel kan gøre.
/b
| |
Mogens Hansen (30-07-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 30-07-03 20:07 |
|
"Bertel Brander" <bertel@post4.tele.dk> wrote in message
news:3f28044f$0$13253$edfadb0f@dread15.news.tele.dk...
[8<8<8<]
> Da det er udefineret hvad der printes med printf, har programmet
> udefineret opførsel. C-standarden sætter ingen begrænsninger for hvad
> et program der har udefineret opførsel kan gøre.
Det er væsentligt at skelne mellem "undefined" og "unspecified".
Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
Det vil sige at det er veldefineret at programmet enten udskriver
10=9
9=8
...
eller
9=9
8=8
...
Der er ikke tale om "undefined".
Se f.eks. C++ Standard §5.2.2-8.
Venlig hilsen
Mogens Hansen
| |
Bertel Brander (30-07-2003)
| Kommentar Fra : Bertel Brander |
Dato : 30-07-03 22:29 |
|
Mogens Hansen wrote:
"Bertel Brander" <bertel@post4.tele.dk> wrote in message
> news:3f28044f$0$13253$edfadb0f@dread15.news.tele.dk...
>
> [8<8<8<]
>
>>Da det er udefineret hvad der printes med printf, har programmet
>>udefineret opførsel. C-standarden sætter ingen begrænsninger for hvad
>>et program der har udefineret opførsel kan gøre.
>
>
> Det er væsentligt at skelne mellem "undefined" og "unspecified".
>
> Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
>
> Det vil sige at det er veldefineret at programmet enten udskriver
> 10=9
> 9=8
> ...
> eller
> 9=9
> 8=8
> ...
>
Jeg, må tilstå at jeg ikke er sikker...
Ud fra en mere pragmatinsk synsvinkel er det vel ligegyldigt
om det undefined eller unspecified, man kan ikke forudse
resultatet, så beskeden må være "Don't do that"
Havde programmet nu set ud som følger:
unsigned int a = 10;
while (a)
printf ("%u = %u\n", --a, --a );
Er der vel ikke tvivl om at det er undefined (altså at alt kan ske).
/b
| |
Mogens Hansen (31-07-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 31-07-03 20:25 |
|
"Bertel Brander" <bertel@post4.tele.dk> wrote in message
news:<3f2837be$0$24644$edfadb0f@dread14.news.tele.dk>...
[8<8<8<]
> Ud fra en mere pragmatinsk synsvinkel er det vel ligegyldigt om det
> undefined eller unspecified, man kan ikke forudse resultatet, så
> beskeden må være "Don't do that"
Jeg er enig i din pragmatiske synvinkel.
Dog syntes jeg at det er væsentligt om det er undefined eller unspecified.
Jeg er af den opfattelse at det oprindelige eksempel har undefined
behaviour, jvf. Søren Sandmann's henvisning.
Hvis det det blot var uspecified ville der ikke være andre tilladte output
end hvad jeg skrev, og der ville ikke være mulighed for f.eks. en uendelig
løkke.
>
> Havde programmet nu set ud som følger:
>
> unsigned int a = 10;
>
> while (a)
> printf ("%u = %u\n", --a, --a );
>
> Er der vel ikke tvivl om at det er undefined (altså at alt kan ske).
Enig.
Venlig hilsen
Mogens Hansen
| |
Niels Dybdahl (30-07-2003)
| Kommentar Fra : Niels Dybdahl |
Dato : 30-07-03 22:36 |
|
> Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
>
> Det vil sige at det er veldefineret at programmet enten udskriver
> 10=9
> 9=8
> ...
> eller
> 9=9
> 8=8
Det er vel lovligt at udnytte flerprocessorsystemer til at beregne
parametrene parallelt. Så er der faktisk væsentligt flere muligheder end de
nævnte.
Niels Dybdahl
| |
Bertel Brander (30-07-2003)
| Kommentar Fra : Bertel Brander |
Dato : 30-07-03 22:56 |
|
Niels Dybdahl wrote:
>>Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
>>
>>Det vil sige at det er veldefineret at programmet enten udskriver
>> 10=9
>> 9=8
>> ...
>>eller
>> 9=9
>> 8=8
>
>
> Det er vel lovligt at udnytte flerprocessorsystemer til at beregne
> parametrene parallelt. Så er der faktisk væsentligt flere muligheder end de
> nævnte.
>
Om "maskinen" har flere processorer er irrelevant, maskinen skal opføre
sig somom der kun er en.
/b
| |
Jens Axel Søgaard (30-07-2003)
| Kommentar Fra : Jens Axel Søgaard |
Dato : 30-07-03 23:38 |
|
Bertel Brander wrote:
> Niels Dybdahl wrote:
>
>>> Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
....
>> Det er vel lovligt at udnytte flerprocessorsystemer til at beregne
>> parametrene parallelt. Så er der faktisk væsentligt flere muligheder
>> end de
>> nævnte.
>>
> Om "maskinen" har flere processorer er irrelevant, maskinen skal opføre
> sig somom der kun er en.
Ikke helt irrelevant.
Hvorfor har man ikke specificeret, at evalueringen af argumenterne
sker i rækkefølge fra venstre mod højre?
Fordelen ved at forlange en venstre-til-højre-rækkefølge er, at
man folk ikke uforvarende kommer til at skrive programmer, som
ikke umiddelbart kan flyttes fra oversætter til oversætter.
Fordelen ved ikke at specificere en venstre-til-højre-rækkefølge er,
at en snedig oversætter kan udnytte registrene fuldt ud ved selv at
kunne bestemme rækkefølgen. Normalt vil oversættere holde evaluerings-
rækkefølgen på et givet kaldsted fast (og så er der en rækkefølge).
Man kan dog godt forestille sig, at man kunne spare et par
stakoperationer ved lade rækkefølgen være bestemt af værdien af
den første parameter (for eksempel om den sand eller falsk).
Men da der nu ikke er specificeret en, at der en rækkefølge, så
kunne man jo udnytte udnytte flere processorer til at udregne
argumenterne. Her vil der heller ikke være tale om en fast
rækkefølge på et givet kaldsted. Men mon ikke overheadet i
de fleste situationer vil gøre den mulighed teoretisk?
--
Jens Axel Søgaard
| |
Soeren Sandmann (31-07-2003)
| Kommentar Fra : Soeren Sandmann |
Dato : 31-07-03 00:33 |
|
Jens Axel Søgaard <usenet@jasoegaard.dk> writes:
> Men da der nu ikke er specificeret en, at der en rækkefølge, så
> kunne man jo udnytte udnytte flere processorer til at udregne
> argumenterne. Her vil der heller ikke være tale om en fast
> rækkefølge på et givet kaldsted. Men mon ikke overheadet i
> de fleste situationer vil gøre den mulighed teoretisk?
Jeg har ikke ret meget forstand på CPU'er, men forholder det ikke
sådan at nogle af dem kan foretage flere beregninger på samme tid? I
så fald giver det C-standarden (ifølge C-FAQ-en) skriver:
Between the previous and next sequence point an object shall have
its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be accessed only to
determine the value to be stored.
god mening, for det betyder at oversætteren kan generere kode der
parallelliserer så godt som muligt uden hensyn til om den samme
variabel læses fra og skrives til på samme tid; det har programmøren
nemlig taget sig af.
Oversætteren skal bare sørge for (a) at skrivninger til en variabel
ikke sker før det skrevne faktisk er blevet beregnet, og (b) at to
udtryk som beregnes mellem forskellige sequence-points, ikke bliver
udregned på samme tid.
| |
Jens Axel Søgaard (31-07-2003)
| Kommentar Fra : Jens Axel Søgaard |
Dato : 31-07-03 00:57 |
|
Soeren Sandmann wrote:
> Jens Axel Søgaard <usenet@jasoegaard.dk> writes:
>>Men da der nu ikke er specificeret en, at der en rækkefølge, så
>>kunne man jo udnytte udnytte flere processorer til at udregne
>>argumenterne. Her vil der heller ikke være tale om en fast
>>rækkefølge på et givet kaldsted. Men mon ikke overheadet i
>>de fleste situationer vil gøre den mulighed teoretisk?
>
>
> Jeg har ikke ret meget forstand på CPU'er, men forholder det ikke
> sådan at nogle af dem kan foretage flere beregninger på samme tid? I
> så fald giver det C-standarden (ifølge C-FAQ-en) skriver:
>
> Between the previous and next sequence point an object shall have
> its stored value modified at most once by the evaluation of an
> expression. Furthermore, the prior value shall be accessed only to
> determine the value to be stored.
>
> god mening, for det betyder at oversætteren kan generere kode der
> parallelliserer så godt som muligt uden hensyn til om den samme
> variabel læses fra og skrives til på samme tid; det har programmøren
> nemlig taget sig af.
>
> Oversætteren skal bare sørge for (a) at skrivninger til en variabel
> ikke sker før det skrevne faktisk er blevet beregnet, og (b) at to
> udtryk som beregnes mellem forskellige sequence-points, ikke bliver
> udregned på samme tid.
Det er godt set, det havde jeg slet ikke skænket en tanke. Det giver en
god ikke-teoretisk nutidig motivation.
Ser vi historisk på det, så er valget vel truffet allerede meget
tidligt, inden parallellisering kom til (hvornår skete det egentlig?)
Derfor gætter jeg på, at det optimering af tildeling ad registre til
variable, der er tænkt på i sin tid.
--
Jens Axel Søgaard
| |
Troels Thomsen (31-07-2003)
| Kommentar Fra : Troels Thomsen |
Dato : 31-07-03 08:31 |
|
Sequence points! , så har jeg også lært noget idag
> Furthermore, the prior value shall be accessed only to
> determine the value to be stored.
Er flg et lovligt eksempel på dette, eller kan nogen finde på noget bedre:
unsigned int a = 2;
int b = (a) ? --a : a;
(det er vel ulovligt med: a = (a) ? --a : a; fordi a bliver modificeret to
gange? )
mvh Troels
| |
Bertel Brander (31-07-2003)
| Kommentar Fra : Bertel Brander |
Dato : 31-07-03 00:41 |
|
Jens Axel Søgaard wrote:
> Bertel Brander wrote:
>
>> Niels Dybdahl wrote:
>>
>>>> Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
>
> ...
>
>>> Det er vel lovligt at udnytte flerprocessorsystemer til at beregne
>>> parametrene parallelt. Så er der faktisk væsentligt flere muligheder
>>> end de
>>> nævnte.
>>>
>> Om "maskinen" har flere processorer er irrelevant, maskinen skal opføre
>> sig somom der kun er en.
>
>
> Ikke helt irrelevant.
Set ud fra C-standarden er der irrelevant, kompileren skal få det
til at se ud somom der kun er en processor.
>
> Hvorfor har man ikke specificeret, at evalueringen af argumenterne
> sker i rækkefølge fra venstre mod højre?
Jeg har ikke skrevet C-standarden, men jeg vil tro at man har valgt
effektivitet over portabilitet.
>
> Men da der nu ikke er specificeret en, at der en rækkefølge, så
> kunne man jo udnytte udnytte flere processorer til at udregne
> argumenterne. Her vil der heller ikke være tale om en fast
> rækkefølge på et givet kaldsted. Men mon ikke overheadet i
> de fleste situationer vil gøre den mulighed teoretisk?
Hvis argumenterne er uafhængige kan kompileren godt sætte flere
processorer til at udregne dem, programmet vil opføre sig somom
der kun var en processor. Hvis ikke de er uafhængige har vi et
problem med reentrance, som C-standarden ikke siger noget om.
Jeg kan godt forestille mig at man kunne opnå fordele ved at
sætte flere processorer til at arbejde med argumenterne samtidig,
men jeg tror ikke det sker i praksis.
/b
| |
Jens Axel Søgaard (31-07-2003)
| Kommentar Fra : Jens Axel Søgaard |
Dato : 31-07-03 00:51 |
|
Bertel Brander wrote:
> Jens Axel Søgaard wrote:
>> Ikke helt irrelevant.
> Set ud fra C-standarden er der irrelevant, kompileren skal få det
> til at se ud somom der kun er en processor.
Ja. Men vi ser på C-standarden og vil gerne forstå, det valg der
er gjort i standarden.
>> Hvorfor har man ikke specificeret, at evalueringen af argumenterne
>> sker i rækkefølge fra venstre mod højre?
>
> Jeg har ikke skrevet C-standarden, men jeg vil tro at man har valgt
> effektivitet over portabilitet.
Ja - men spørgsmålet var nu retorisk
>> Men da der nu ikke er specificeret en, at der en rækkefølge, så
>> kunne man jo udnytte udnytte flere processorer til at udregne
>> argumenterne. Her vil der heller ikke være tale om en fast
>> rækkefølge på et givet kaldsted. Men mon ikke overheadet i
>> de fleste situationer vil gøre den mulighed teoretisk?
>
>
> Hvis argumenterne er uafhængige kan kompileren godt sætte flere
> processorer til at udregne dem, programmet vil opføre sig somom
> der kun var en processor. Hvis ikke de er uafhængige har vi et
> problem med reentrance, som C-standarden ikke siger noget om.
> Jeg kan godt forestille mig at man kunne opnå fordele ved at
> sætte flere processorer til at arbejde med argumenterne samtidig,
> men jeg tror ikke det sker i praksis.
Det tror jeg heller ikke.
--
Jens Axel Søgaard
| |
Martin M. Pedersen (31-07-2003)
| Kommentar Fra : Martin M. Pedersen |
Dato : 31-07-03 17:33 |
|
"Jens Axel Søgaard" <usenet@jasoegaard.dk> wrote in message
news:3f284902$0$97226$edfadb0f@dread12.news.tele.dk...
> Hvorfor har man ikke specificeret, at evalueringen af argumenterne
> sker i rækkefølge fra venstre mod højre?
>
> Fordelen ved at forlange en venstre-til-højre-rækkefølge er, at
> man folk ikke uforvarende kommer til at skrive programmer, som
> ikke umiddelbart kan flyttes fra oversætter til oversætter.
Det afhænger helt af kalds-konvention, hvilken rækkefølge der er mest
naturligt for compileren. I kald til "C" funktioner, er det mest naturligt
at evaluere fra højre-til-venstre, da det er den rækkefølge argumenterne
skal push'es i. Omvendt ved f.eks. Windows API-kald. Jeg tror, det vil være
forholdsvist dyrt, hvis compileren ikke kan bruge den "naturlige"
rækkefølge.
mvh.
Martin
| |
Niels Dybdahl (31-07-2003)
| Kommentar Fra : Niels Dybdahl |
Dato : 31-07-03 19:20 |
|
> Hvorfor har man ikke specificeret, at evalueringen af argumenterne
> sker i rækkefølge fra venstre mod højre?
Langt de fleste C-compilere evaluerer fra højre mod venstre, fordi det er
det nemmeste ved sprog som overfører parametre via stakken og som tillader
variabelt antal parametre.
Niels Dybdahl
| |
Niels Dybdahl (31-07-2003)
| Kommentar Fra : Niels Dybdahl |
Dato : 31-07-03 19:16 |
|
> > Det er vel lovligt at udnytte flerprocessorsystemer til at beregne
> > parametrene parallelt. Så er der faktisk væsentligt flere muligheder end
de
> > nævnte.
> >
> Om "maskinen" har flere processorer er irrelevant, maskinen skal opføre
> sig somom der kun er en.
En processor kan også programmeres til at evaluere parametrene i tilfældig
rækkefølge, eller simuleret parallelt, så dit argument ændrer vel ikke noget
?
Niels Dybdahl
| |
Mogens Hansen (31-07-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 31-07-03 20:24 |
|
"Niels Dybdahl" <Niels@Dybdahl.dk> wrote in message
news:<3f283a3f$0$76140$edfadb0f@dread11.news.tele.dk>...
> > Evalueringsrækkefølgen af funktions argumenterne er uspecificeret.
> >
> > Det vil sige at det er veldefineret at programmet enten udskriver
> > 10=9
> > 9=8
> > ...
> > eller
> > 9=9
> > 8=8
>
> Det er vel lovligt at udnytte flerprocessorsystemer til at beregne
> parametrene parallelt.
Nej ikke generelt.
Det vil være en optimering, som compileren eller CPU'en laver.
Derfor må det ikke være observerbart på programmets opførsel om optimeringen
er foretaget eller ej.
Derfor kan man tænke på det som sekventiel eksekvering, uanset hvordan rent
faktisk bliver udført.
> Så er der faktisk væsentligt flere muligheder
> end de nævnte.
Vi er nok nødt til at dele spørgsmålet op i 2 dele:
1. Det er uspecificeret hvilken rækkefølge funktions argumenter evalueres
i.
2. Det er giver udefineret opførsel hvis der mellem 2 sequence points
ændres en variabel og den pågældende variabel læses af andre grunde en for
at bestemme den nye værdi - sådan som Søren Sandmann påpegede.
Idet eksemplet i det oprindelige spørgsmål falder ind under punkt 2, og
dermed har udefineret opførsel er hvad som helst tilladt, og som sådan er
der væsentligt flere muligheder end hvad jeg nævnte uanset om det kører på
enkelt- eller fler-processorsystemer.
Hvis vi alene kigger på punkt 1, skal
foo(expr_1, expr_2);
enten udføres som
T1 expr_1_result = expr_1;
T2 expr_2_result = expr_2;
foo(expr_1_result, expr_2_result);
eller
T2 expr_2_result = expr_2;
T1 expr_1_result = expr_1;
foo(expr_1_result, expr_2_result);
expr_1 og expr_2 må ikke evalueres parallelt, hvis det på nogen måde kan
skelnes fra at de bliver eksekveret sekventielt.
Venlig hilsen
Mogens Hansen
| |
Soeren Sandmann (30-07-2003)
| Kommentar Fra : Soeren Sandmann |
Dato : 30-07-03 20:11 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> writes:
> "Soeren Sandmann" <sandmann@daimi.au.dk> wrote
>
> [8<8<8<]
> > Faktisk er det ikke engang påkrævet at der _er_ en
> > evalueringsrækkefølge. Det er ikke veldefineret hvad det ovenstående
> > gør, så resultatet kan fx være en uendelig løkke eller mærkeligere.
>
> Hvorfra har du den opfattelse ?
Fra FAQ'en for comp.lang.c. Som jeg læser
http://www.eskimo.com/~scs/C-faq/q3.8.html ,
så er der ikke noget sequence point mellem i og --i, hvilket betyder
at programstumpens opførsel er udefineret af C-standarden. Kommærne i
et funktionskald er ikke kommaoperatorer, så de giver ikke anledning
til sequence points.
| |
Mogens Hansen (31-07-2003)
| Kommentar Fra : Mogens Hansen |
Dato : 31-07-03 20:23 |
|
"Soeren Sandmann" <sandmann@daimi.au.dk> wrote in message
news:<ye865ljomo2.fsf@horse06.daimi.au.dk>...
> "Mogens Hansen" <mogens_h@dk-online.dk> writes:
>
> > "Soeren Sandmann" <sandmann@daimi.au.dk> wrote
> >
> > [8<8<8<]
> > > Faktisk er det ikke engang påkrævet at der _er_ en
> > > evalueringsrækkefølge. Det er ikke veldefineret hvad det
> > > ovenstående gør, så resultatet kan fx være en uendelig løkke eller
> > > mærkeligere.
> >
> > Hvorfra har du den opfattelse ?
>
> Fra FAQ'en for comp.lang.c. Som jeg læser
>
> http://www.eskimo.com/~scs/C-faq/q3.8.html ,
>
> så er der ikke noget sequence point mellem i og --i, hvilket betyder
> at programstumpens opførsel er udefineret af C-standarden. Kommærne i
> et funktionskald er ikke kommaoperatorer, så de giver ikke anledning
> til sequence poin
Det har du vist ret i - tak.
Jeg fokuserede kun på at rækkefølgen som argumenter evalueres i er
uspecificeret.
Venlig hilsen
Mogens Hansen
| |
|
|