Toon posts:

[c++] de ++operator

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met een programma om mijn C++ kennis te vergroten. Maar ik krijg een vreemde fout met de ++operator. Hij schijnt niet naar behoren te werken. Ik doe het volgende:

C++:
1
2
3
4
5
6
Customer CustomerList::next()
{
    if( (customerCount+1) >= MAX_NUMBER_OF_CUSTOMERS)
        return customer[customerCount];
    return customer[++customerCount] = Customer(customerCount);
}


Text output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-------------0
[customer=0]
[100|Marlboro|5.35][1]

-------------1
[customer=0]
[200|krant|1.25][2]

-------------2
[customer=1]
[200|krant|1.25][1]
[202|Wenskaar|2.25][1]

-------------3
[customer=2]
[202|pr0n|2.25][4]


Wat ik wil is dat hij de variable int customerCount eerst verhoogt en deze vervolgens als index gebruikt in de array. Hij verhoogt hem echter pas erna. Als ik ik hem apart eerst verhoog dan werkt het wel:

C++:
1
2
3
4
5
6
7
Customer CustomerList::next()
{
    if( (customerCount+1) >= MAX_NUMBER_OF_CUSTOMERS)
        return customer[customerCount];
    customerCount++;
    return customer[customerCount] = Customer(customerCount);
}


Text output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-------------0
[customer=0]
[100|Marlboro|5.35][1]

-------------1
[customer=1]
[200|krant|1.25][2]

-------------2
[customer=2]
[200|krant|1.25][1]
[202|Wenskaar|2.25][1]

-------------3
[customer=3]
[202|pr0n|2.25][4]


in principe werkt ie nu, maar ik wil weten wat hier aan mis gaat. :) |:(

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

C++:
1
return customer[++customerCount] = Customer(customerCount);


Dat is leuk, welke customerCount wordt nu eerst geevalueerd? ;)

[ Voor 6% gewijzigd door .oisyn op 16-10-2003 20:23 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

.oisyn schreef op 16 October 2003 @ 20:22:
Dat is leuk, welke customerCount wordt nu eerst geevalueerd? ;)
My thoughts exactly :) Wat gebeurt er bij
C++:
1
return customer[customerCount] = Customer(++customerCount);
:?


Journalism is printing what someone else does not want printed; everything else is public relations.


Verwijderd

Topicstarter
Damn, dat is hem. Tnx!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Rataplan schreef op 16 October 2003 @ 20:25:
[...]
My thoughts exactly :) Wat gebeurt er bij
C++:
1
return customer[customerCount] = Customer(++customerCount);
:?
hoewel dat wel zou kunnen werken, is het in principe undefined behaviour.
5.0 - 4
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified
bron

Ik zou dus eerst customerCount incrementen, en daarna pas die statement uitvoeren

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

.oisyn schreef op 16 October 2003 @ 20:33:
hoewel dat wel zou kunnen werken, is het in principe undefined behaviour.
Ik wou het net vragen, het leek me al vrij onoverzichtelijk. Tu :>
edit:
* bookmarks bron

[ Voor 14% gewijzigd door Rataplan op 16-10-2003 20:38 ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
.oisyn schreef op 16 October 2003 @ 20:33:
[...]
hoewel dat wel zou kunnen werken, is het in principe undefined behaviour.
Waarom?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Door die quote die daaronder staat in mijn post. Of interpreteer ik dat verkeerd?
(maw, staat het vast dat de rhs van de = operator altijd wordt geevalueerd voor de lhs?)

.edit: ik zie in de specs van de assignment operator (5.17) niets staan over de volgorde van evaluation, alleen dat ie rechts-associatief is. Maar zegt associativiteit ook automatisch iets over de volgorde van evaluatie?

[ Voor 82% gewijzigd door .oisyn op 16-10-2003 20:56 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:27

crisp

Devver

Pixelated

In javascript is de volgorde van evaluatie mbt de post-increment wel beschreven, en is dit dus expected behaviour:

JavaScript:
1
2
3
4
5
var a = [];
var i = 0;

a[i++] = 1; // kent 1 toe aan a[0] en verhoogt dan i met 1
a[++i] = 1; // verhoogt i met 1 en kent dus 1 toe aan a[2]

Intentionally left blank


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

crisp: dat is het punt ook niet, het is ook perfect gespecificeerd in C++, op dezelfde manier als in javascript overigens (ook wel logisch, die heeft het geleend van Java, die het weer van C++ geleend heeft :+)

Maar plaats de i nu eens 2x in dezelfde expressie, wat dan?

Overigens, een leuk experimentje, wat is de output van dit programma?
C++:
1
2
3
4
5
6
7
8
#include <iostream>

int main ()
{
    int i = 1;
    ++i = ++i;
    std::cout << i << std::endl;
}

[ Voor 48% gewijzigd door .oisyn op 16-10-2003 21:08 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:27

crisp

Devver

Pixelated

.oisyn schreef op 16 October 2003 @ 21:06:
crisp: dat is het punt ook niet, het is ook perfect gespecificeerd in C++, op dezelfde manier als in javascript overigens (ook wel logisch, die heeft het geleend van Java, die het weer van C++ geleend heeft :+)

Maar plaats de i nu eens 2x in dezelfde expressie, wat dan?
van links naar rechts uitgevoerd; eerst wordt dus de expressie links geevalueerd, vervolgens de uitkomst van de expressie rechts daaraan toegekent:
JavaScript:
1
2
3
4
5
6
7
var a = [0,0,0];
var b = [1,2,3];
var i = 0;

a[++i] = b[i];

alert(a); // [0,2,0]
Overigens, een leuk experimentje, wat is de output van dit programma?
C++:
1
2
3
4
5
6
7
8
#include <iostream>

int main ()
{
    int i = 1;
    ++i = ++i;
    std::cout << i << std::endl;
}
2 = 3 ??? :? Syntax Error lijkt me

[ Voor 3% gewijzigd door crisp op 16-10-2003 21:14 ]

Intentionally left blank


Verwijderd

Topicstarter
.oisyn schreef op 16 October 2003 @ 21:06:Overigens, een leuk experimentje, wat is de output van dit programma?
C++:
1
2
3
4
5
6
7
8
#include <iostream>

int main ()
{
    int i = 1;
    ++i = ++i;
    std::cout << i << std::endl;
}
3
getest en wel.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Syntax Error lijkt me
Heeft niet zoveel met syntax te maken ;)

Denk eerder iets in de trant van 'lvalue required' ofzo. Ligt aan de compiler natuurlijk.

edit:
|:( * drm lult stom
het resultaat van een ++i is natuurlijk gewoon i links van een =

3, dan, dus :P

[ Voor 27% gewijzigd door drm op 16-10-2003 21:21 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

++i is een prima l-value :)

[ Voor 186% gewijzigd door .oisyn op 16-10-2003 21:30 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

.oisyn:
++i is een prima l-value :)
Dat zeg ik :+

gcc (2.96) heeft er overigens geen enkele moeite mee en poept idd gewoon 3 uit.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Limhes
  • Registratie: Oktober 2001
  • Laatst online: 19-08 19:06
Dat is juist het hele punt.

.oisyn geeft aan (althans denkt/vermoedt) dat het niet gespecificeerd is. Als jij dan met een of andere compiler (waarvan de maker die niet bestaande specificaties dus ook niet heeft) deze expressie getest hebt is het dus afhankelijk van die betreffende compiler wat de uitkomst is.

Mij lijkt van rechts naar links trouwens logischer. Waarom weet ik niet, maar het voelt beter; je kent immers steeds het rechter deel toe aan het linker, dus wil je als eerste weten wat het rechter deel is.

  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

Volgens mij is het ook onmogelijk om hier 2 uit te krijgen (ik neem tenminste aan dat dat de crux van het experiment was), omdat de prio van de ++ hoger is dan die van de assignment; dus i is al drie voordat het assignment wordt uitgevoerd :+

Ik neem tenminste aan dat de advocaat van de duivel wilde dat de lsh werd berekend, en vervolgens de assignment "= 2" eroverheen moest waardoor de linker ++ "verviel" :)

[ Voor 4% gewijzigd door Rataplan op 16-10-2003 21:28 . Reden: :++ is geen smiley :D ]


Journalism is printing what someone else does not want printed; everything else is public relations.


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 20:27

crisp

Devver

Pixelated

JS geeft dus een syntax error in deze beide gevallen:

code:
1
2
++i = 4;
i++ = 4;


hoewel mijn boek beweerd dat pre of postincrements in JS van type lvalue zijn met right-to-left assiociativity

* crisp gooit boek in de prullenbak

Intentionally left blank


  • Rataplan
  • Registratie: Oktober 2001
  • Niet online

Rataplan

per aspera ad astra

crisp schreef op 16 October 2003 @ 21:29:
* crisp gooit boek in de prullenbak
* Rataplan kan nog wel een JS-boek gebruiken. Als ik de porto nou betaal...?


Journalism is printing what someone else does not want printed; everything else is public relations.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

idd, hier ook, maar volgens mij is het ongelooflijk compiler specifiek, en bovendien is dat antwoord niet echt intuitief

Immers, je doet ++i = ++i
Oftewel, je assignt het resultaat van ++i aan ++i. En de door mij gebruikte compiler (msvc++ 7.1) evalueert de = van rechts naar links. Oftewel, de ++i aan de rechterkant wordt eerst geevalueerd, en i wordt dus 2. Dan staat er dus:
C++:
1
++i = 2;


vervolgens wordt de linkerkant geevalueerd, en i wordt 3. Daarna wordt de 2 geassigned aan i, waardoor je dus zou denken dat i weer gelijk wordt aan 2.

Ik heb wat getest, door oa de int te vervangen door een klasse met overloaded operators, en te kijken in welke volgorde alles nu gebeurt.

Er is op zich iets te zeggen voor het resultaat van 3. De rhs is namelijk een int &, en geen int, dus de waarde wordt pas gepakt op het moment van de assignment. Echter, bij dit stukje code:

C++:
1
2
3
4
5
6
7
int func (int i) { return i; }

int main ()
{
    int i = 1;
    ++i = func (++i);
}


is de volgorde als volgt (msvc++ 7.1 nogmaals):
eerst wordt de rhs ++i geevalueerd. i is dan 2. Dan wordt de lhs geevalueerd, i wordt 3. Daarna wordt de functie aangeroepen, die krijgt dus 3 als parameter, en niet 2. Vervolgens wordt die 3 geassigned aan i, maar die was al 3 dus er veranderd niets.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
helaas allemaal. Mijn subtiele vraagje was een opzetje. Customer::operator= is een functie, en functiecalls hebben sequence points. Je weet alleen niet wat er aan welke kant van het sequence point gebeurt. Dat heet unspecified.
De order of evaluation is namelijk unspecified in C++, met een paar logische uitzonderingen: een functie begint pas nadat de argumenten zijn geevalueerd en zo.

De discussie met int is een ander verhaal. Dat is een built-in operator zonder sequence point. De uitdrukking i++ = i++ verandert i dus twee maal zonder tussenliggend sequence point, en dat is dus wel undefined behavior. i mag dus 1,2,3,4 worden, andere variabelen mogen worden overschreven, je programma mag crashen en als je monitor in de fik vliegt is het nog steeds volgens de standaard correct.

[ Voor 12% gewijzigd door MSalters op 16-10-2003 22:10 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 16 October 2003 @ 22:09:
als je monitor in de fik vliegt is het nog steeds volgens de standaard correct.
* curry684 gaat eens een andere taal leren...

Is VB een beetje leuk? 8)7

Professionele website nodig?


  • sphere
  • Registratie: Juli 2003
  • Laatst online: 20:07

sphere

Debian abuser

Bekend is ook dat het volgende unpredictable code geeft met verschillende C compilers:
C:
1
2
3
4
5
6
int i,o;
for (i=0;i<100;i++)
{
o = i++*i++;
printf(%i\n,o);
}

http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

sphere2:
Bekend is ook dat het volgende unpredictable code geeft met verschillende C compilers:
C:
1
2
3
4
5
6
int i,o;
for (i=0;i<100;i++)
{
o = i++*i++;
printf(%i\n,o); /*  <-  */
}
Ik kan wel voorspellen wat een compiler doet bij deze code :+

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

drm schreef op 21 October 2003 @ 08:11:
[...]
Ik kan wel voorspellen wat een compiler doet bij deze code :+
Ik gok uit het blote hoofd op iets in de richting van "No valid statement found preceding %" of zo :)

En met double quotes identiek aan alle eerder gegeven voorbeelden :z

Professionele website nodig?

Pagina: 1