You are on page 1of 9

signup

StackOverflowisaquestionandanswersiteforprofessionalandenthusiastprogrammers.It's100%free,no
registrationrequired.

login

tour

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

5/13/2015

help

stackoverflowcareers

Takethe2minutetour

WithCarrays,whyisitthecasethata[5]==5[a]?
AsJoelpointsoutinStackOverflowpodcast#34,inCProgrammingLanguage(aka:K&R),thereismentionofthispropertyofarrays
inC:a[5]==5[a]
Joelsaysthatit'sbecauseofpointerarithmeticbutIstilldon'tunderstand.Whydoes a[5]==5[a] ?
c arrays pointers pointerarithmetic

editedDec4'13at20:26

askedDec19'08at17:01

einpoklum
4,211

Dinah
26

61

17.4k

22

95

124

wouldsomethinglikea[+]alsoworklike*(a++)OR*(++a)?EgonMay13'10at16:14

14 @Egon:That'sverycreativebutunfortunatelythat'snothowcompilerswork.Thecompilerinterprets
a[1] asaseriesoftokens,notstrings:*({integerlocationof}a{operator}+{integer}1)isthesameas*
({integer}1{operator}+{integerlocationof}a)butisnotthesameas*({integerlocationof}a{operator}+
{operator}+) Dinah May13'10at17:24
4

AninterestingcompoundvariationonthisisillustratedinIllogicalarrayaccess ,whereyouhave char


bar[];intfoo[]; and foo[i][bar] isusedasanexpression. JonathanLeffler Oct17'12at6:38

@EldritchConundrum,whydoyouthink'thecompilercannotcheckthattheleftpartisapointer'?Yes,it
can.It'struethat a[b] = *(a+b) foranygiven a and b ,butitwasthelanguagedesigners'free
choicefor + tobedefinedcommutativeforalltypes.Nothingcouldpreventthemfromforbidding i+p
whileallowing p+i .AndreyChernyakhovskiy Mar14'14at19:46

@AndreyOneusuallyexpects + tobecommutative,somaybetherealproblemischoosingtomake
pointeroperationsresemblearithmetic,insteadofdesigningaseparateoffsetoperator.
EldritchConundrumMar18'14at10:36

13Answers

TheCstandarddefinesthe [] operatorasfollows:
a[b]==*(a+b)

Therefore a[5] willevaluateto:


*(a+5)

and 5[a] willevaluateto:


*(5+a)

andfromelementaryschoolmathweknowthoseareequal.
Thisisthedirectartifactofarraysbehavingaspointers," a "isamemoryaddress." a[5] "isthe
valuethat's5elementsfurtherfrom" a ".Theaddressofthiselementis" a+5 ".Thisisequalto
offset" a "from" 5 "elementsatthebeginningoftheaddressspace( 5+a ).
editedApr18'13at15:29
Let_Me_Be
18.1k

answeredDec19'08at17:04
MehrdadAfshari

45

90

230k

52

617

678

188 Iwonderifitisn'tmorelike*((5*sizeof(a))+a).Greatexplainationthough.JohnMacIntyreDec19'08
at17:06

I'mtotallyanal...soIcouldn'tresist....theassignmentoperatorinthetitleisalsodrivingmebananas
...butI'mnotgoinggoingtobethatbigofaknob.)JohnMacIntyreDec19'08at17:10

Sorrythatthe"assignmentoperator"isdrivingyounuts,howeverI'maskingaboutmathematical
equivalencynotrepresentingacodesnippetsotheequalssigniscorrect.Thanksfortheanswers!
Dinah Dec19'08at17:11

81

John,nothesizeofisn'tneeded.it'sautomaticallyincrementedbythesizeofJohannesSchaublitb
Dec19'08at17:12

Whyissizeof()takenintoaccount.Ithoughtthepointerto'a'istothebeginningofthearray(ie:the0
element).Ifthisistrue,youonlyneed*(a+5).Myunderstandingmustbeincorrect.What'sthecorrect
reason? Dinah Dec19'08at17:15

Ifyouhaveanarrayof4byteintegers,a[1]a[0]=4(4bytesdiefferncebetweenthetwopointers).
TrebDec19'08at17:17

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

1/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

Dinah,noyourunderstandingiscorrect.only*(a+5)isneeded.thecompilertranslatesitintoassembler
codethatoffsetstheaddressofa'sfirstelementby(5*sizeofa[0])bytes.JohannesSchaublitb
Dec19'08at17:18

36

@Dinah:FromaCcompilerperspective,youareright.NosizeofisneededandthoseexpressionsI
mentionedareTHESAME.However,thecompilerwilltakesizeofintoaccountwhenproducingmachine
code.Ifaisanintarray,a[5]willcompiletosthlikemoveax,[ebx+20]insteadof[ebx+5]
MehrdadAfshariDec19'08at17:18

20

It'sdoneautomatically.Sinceonlyaddinganhalfelementtoapointer(thuspointinginthemiddleof
someelementisn'tgoingtomakesenseanyway.andTreb,no&a[1]&a[0]isalwaysgoingtobe1for
alltypes(notonly4bytesintegers)JohannesSchaublitbDec19'08at17:18

@Dinah:Aisanaddress,say0x1230.Ifawasin32bitintarray,thena[0]isat0x1230,a[1]isat
0x1234,a[2]at0x1238...a[5]atx1244etc.Ifwejustadd5to0x1230,weget0x1235,whichiswrong.
JamesCurranDec19'08at17:21

Mehrdad.ithinkthatisbecausewecommentonthisallthetime.soitwillbepushedupinthelistof
recentdiscussionsandthenpplwillvote:)soit'salwaysagoodideaifyouwantmorepointsto
commentonyourself,thenremovethecommenthahaJohannesSchaublitbDec19'08at17:23

@James:bingo.That'swhatIneededtosee.Ikeptseeingsizeof()andthinkingcount()andgetting
mightilyconfused.Notmybrightestmoment.Thankyou! Dinah Dec19'08at17:27

@DinahtheassignmentoperatorcommentwasjustatongueincheekcommentabouthowanalIam.
)...Iknewwhatyoumeant,andI'msureeverybodyelsedidaswell.Greatquestionbtw,Iwasjust
listeningtotheSOpodcastwheretheyweretalkingaboutit.JohnMacIntyreDec19'08at18:25

Sointhe5[a]case,thecompilerissmartenoughtouse"*((5*sizeof(a))+a)"andnot"*(5+(a*
sizeof(5)))"?Note:Iguessso.ItriedthisinGCCanditworked.Harvey Dec22'08at18:27

22

@sr105:That'saspecialcaseforthe+operator,whereoneoftheoperandsisapointerandtheotheran
integer.Thestandardsaysthattheresultwillbeofthetypeofthepointer.Thecompiler/hastobe/
smartenough.aibDec23'08at2:08

Mehrdad,ithinkthecommentthingdon'tworkanymore.ifonecomments,it'snotfloatingtothetop:/
JohannesSchaublitbFeb11'09at16:13

commentsneverfloatedtothetopinmymemory johnc Mar3'09at8:01

Whenyouaddanintegertoapointer,thecompilerknowswhattypethepointerpointsto(soifaisan
int*,it's4bytesorwhatever...)socanperformthearithmeticright.Basicallyifyoudo"p++"thenp
shouldbeadjustedtopointtothenextobjectinmemory."p++"isbasicallyequivalentto"p=p+1",so
thedefinitionofpointeradditionmakeseverythinglineup.Alsonoteyoucan'tdoarithmeticwithpointers
oftype void* .araqnidApr18'09at1:03

Iwouldsomuchliketoupvoteit,butthe"Thisisthedirectartifactofarraysbeingpointers"disturbsthe
otherwisesogoodanswer:(Isuspectifyousaid"...ofarraysbeingconvertedtopointers",morepeople
includingmewouldupvote.JohannesSchaublitbSep21'09at15:18

@litb:Iunderstandyourconcernandpotentially"misleading"people.However,Iwantedtokeep
simplicityoftheanswer,asinthiscontext,thearraydecaystoapointer.Ichanged"beingapointer"to
"behavingaspointers."Ihopethat'sOK.Thanksforthecomment,btw.MehrdadAfshariSep21'09at
16:25

freeworld.thc.org/root/phun/unmaintain.htmlmentionsthisasagoodtacticforobfuscation,givingthe
example myfunc(6291,8)[Array]; where myfunc issimplythemodulofunction(that'sequivalentto
Array[3] ) fahadsadah May23'10at12:16

@MehrdadIthinkthemainreasonbehindthispostgettingupvotedmorethanthatexploitpost(which
definitelydeservestobeonthetop)isthatthisoneaddressesarelativelysimplerproblemandhence
morepeopletendtounderstandthis.Theanatomyoftheexploitisnotthissimpleandmostpeoplewill
justskipit:)AmarghoshNov12'10at5:33

12

"fromelementaryschoolmathweknowthoseareequal"Iunderstandthatyouaresimplifying,butI'm
withthosewhofeellikethisisoversimplifying.It'snotelementarythat *(10+(int*)13)!=*((int
*)10+13) .Inotherwords,there'smoregoingonherethanelementaryschoolarithmetic.The
commutativityreliescriticallyonthecompilerrecognizingwhichoperandisapointer(andtowhatsizeof
object).Toputitanotherway, (1apple+2oranges)=(2oranges+1apple) ,but (1apple+2
oranges)!=(1orange+2apples) . LarsH Dec1'10at20:54

@LarsH:You'reright.I'dsayit'smoreanalogousto (10in+10cm) ratherthanapplesandoranges(you


canmeaningfullyconvertonetoanother).MehrdadAfshariDec1'10at21:53

@Mehrdad:Fairenough.Maybeabetteranalogyisadatevs.atimeinterval,asin (May1st2010+3
weeks) . LarsH Dec1'10at23:37

"Thisisthedirectartifactofarraysbehavingaspointers":no,arraysdonotbehaveaspointersatall.
LightnessRacesinOrbitAug14'11at15:14

'"a"isamemoryaddress':no,nomorethan x isamemoryaddressifyouwrite intx; .Thenameof


thearraycandecay toapointertothefirstelementofthatarray,though.LightnessRacesinOrbit
Aug14'11at15:14

@TomalakIunderstand.Thereareplentyofplacesthatitwasrelevantandwe'vediscussedit.However,
whilethequestionspecificallyasksaboutthereasonwhyitworksthewayitdoes.Ican'timaginethis
beingthebehaviorof 5[a] ifintheoriginalimplementationofC,pointersweren'treallybinaries
representingmemoryaddressesdirectlyunderstandablebytheCPU.Ifwewanttobetoopedantic,the
answer(tothisquestionandmanymore)is:"Becausethestandarddefinesthebehaviorof [] operator
on int typesononesideandarrayorpointertypesonanotherassuch."MehrdadAfshariAug14
'11at22:21

@Jim:No,it'sbecausethetypes ,notthevalues,arethesame.Furthermore,elementaryschool
arithmeticcannotbeappliedblindlytoarithmeticoperators.Consider INT_MAX5+1 vs INT_MAX+
15 . BenVoigt Apr5'13at17:27

@Jim:Hardly.Thetypeof a andthetypeof 99 arecertainlynotthesameinthisquestion.


BenVoigtApr5'13at21:44

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

2/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

@Jim:Whatisitcalledwhenyouedityourcommentinordertomakemyresponselookstupid?Youjust
havetolookupafewcomments,toseethattypeDOESmatter. (10+(int*)13)!=((int*)10+
13) andthatwasalreadypointedout. BenVoigt Apr6'13at0:38

Also,myclaimthat"elementaryschoolarithmeticcannotbeappliedblindlytoarithmeticoperators"
needsonlyoneexampletoprovethatfurtherconsideration,notblindapplication,isnecessary.AndIcan
provideseveralexamples.Here'sanothercasewheretypeisimportant: Ta=7.0;doublex=a/
2.0; Clearlywhether a is int or double makesahugedifferenceintheanswer. BenVoigt Apr6
'13at0:41

Moreexamplesarepossible,duetolimitedrangeandprecisionoffloatingpointtypes.TheexampleI
choseoriginally,Ichosebecauseitinvolvesintegeraddition,sameastheproblemunderdiscussion.
BenVoigtApr6'13at0:45

@BenVoigtActuallyIthinkyourexampleshouldbe doublex=a/2; .Ifit's 2.0 theresultwillbe


double ,regardlessofwhether a isan int ora double . Dukeling Jul30'13at10:36

Whatexactlyinelementaryschoolarithmeticssaysthataddingvaluesofcompletelydifferenttypes
mustalwaysbecommutative?hamstergeneJun28'14at20:36

@hamstergeneElementaryschoolmathdoesnottalkabouttypes.MyanswertotheOPquestionfor
youwouldbeTheOneandOnlyTrueAnswer:"becausetheCstandardsaysso."MehrdadAfshari
Jun30'14at1:53

@JohnMacIntyreEvenifitisn'tautomaticallyincremented,shouldn'titbe *((5*sizeof(*a))+a)
insteadof *((5*sizeof(a))+a) ?BolunZhangJul17'14at17:35

fromelementaryschoolmathweknowthoseareequal,wellit'struethatwelearnthatadditionis
commutative,butinthecaseofvaluesofthesametype!Soitisnotobviousthataddingapointerand
anintegerisacommutativeoperation!Butthisisdefinedbythestandard...Thisisnolessobviousthan
adding5toanaddressdoesnotgiveaddress+5,butaddress+5*sizeof(type)!Sopointerarithmeticisnot
soobvious.JeanBaptisteYuns Nov18'14at8:19

@JeanBaptisteYunsYes.Thetechnicalanswertothequestionis"becausethelanguagespecification
says *(p+5) isequalto *(5+p) and a[b] equals *(a+b) ".However,therationalefor *(p+5)
beingequalto *(5+p) isindeedconsistencywith"elementaryschoolmath".MehrdadAfshariNov19
'14at3:09

Forsure,butconsistentwithelementarymathisnotarequirementinpointerarithmetic.Thesumis
"typed"withthepointer'stypesoitisnotso"natural",sowhywouldyoulikeittobecommutative?Just
becausethecodeproducedinassemblydoesn'thavetype?JeanBaptisteYuns Nov19'14at6:58

@JeanBaptisteYunsIt'snotarequirement.ItisadesigndecisiontheClanguagedesignersmade
presumablytoremainconsistentwithcommutativityoftheadditionoperator.Sure,nothingisrequiredin
thestrictestsensewhenyouaredesigningalanguage.MehrdadAfshariNov19'14at7:21

Becausearrayaccessisdefinedintermsofpointers. a[i] isdefinedtomean *(a+i) ,which


iscommutative.
editedMay13'11at13:47

answeredDec19'08at17:05
DavidThornley
40.8k

60

125

13 Arraysarenotdefinedintermsofpointers,butaccess tothemis.LightnessRacesinOrbitMay12'11
at23:20
1

Iwouldadd"soitisequalto *(i+a) ,whichcanbewrittenas i[a] ".JimBalterApr5'13at22:11

Iwouldsuggestyouincludethequotefromthestandard,whichisasfollows:6.5.2.1:2Apostfix
expressionfollowedbyanexpressioninsquarebrackets[]isasubscripteddesignationofanelementof
anarrayobject.Thedefinitionofthesubscriptoperator[]isthatE1[E2]isidenticalto(*((E1)+(E2))).
Becauseoftheconversionrulesthatapplytothebinary+operator,ifE1isanarrayobject(equivalently,
apointertotheinitialelementofanarrayobject)andE2isaninteger,E1[E2]designatestheE2th
elementofE1(countingfromzero).Vality Feb17at21:41

And,ofcourse
"ABCD"[2]==2["ABCD"]=='C'

Themainreasonforthiswasthatbackinthe70'swhenCwasdesigned,computersdidn'thave
muchmemory(64KBwasalot),sotheCcompilerdidn'tdomuchsyntaxchecking.Hence
" X[Y] "wasratherblindlytranslatedinto" *(X+Y) "
Thisalsoexplainsthe" += "and" ++ "syntaxes.Everythingintheform" A=B+C "hadthe
samecompiledform.But,ifBwasthesameobjectasA,thenanassemblyleveloptimization
wasavailable.Butthecompilerwasn'tbrightenoughtorecognizeit,sothedeveloperhadto( A
+=C ).Similarly,if C was 1 ,adifferentassemblyleveloptimizationwasavailable,andagainthe
developerhadtomakeitexplicit,becausethecompilerdidn'trecognizeit.(Morerecently
compilersdo,sothosesyntaxesarelargelyunnecessarythesedays)
editedOct7'09at15:52

answeredDec19'08at17:07

Dinah
17.4k

JamesCurran
22

95

124

62.8k

19

120

201

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

3/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

82 Actually,thatevaluatestofalsethefirstterm"ABCD"[2]==2["ABCD"]evaluatestotrue,or1,and1!=
'C':DJonathanLefflerDec19'08at17:16
3

@Jonathan:sameambiguityleadtotheeditingoftheoriginaltitleofthispost.Arewetheequalmarks
mathematicalequivalency,codesyntax,orpseudocode.Iarguemathematicalequivalencybutsince
we'retalkingaboutcode,wecan'tescapethatwe'reviewingeverythingintermsofcodesyntax.
Dinah Dec19'08at17:26

12 Isn'tthisamyth?Imeanthatthe+=and++operatorswerecreatedtosimplifyforthecompiler?Some
codegetsclearerwiththem,anditisusefulsyntaxtohave,nomatterwhatthecompilerdoeswithit.
ThomasPadronMcCarthy Dec19'08at17:44
2

+=and++hasanothersignificantbenefit.ifthelefthandsidechangessomevariablewhileevaluated,the
changewillonlydoneonce.a=a+...willdoittwice.JohannesSchaublitbDec19'08at17:49

Heardthat+=reducestheoddsformistakesasyouwritevariablenamestwotimesratherthanthree...
LiranOreviApr21'09at8:02

a=a+withobjectsoftenleadstounoptimizedcopiesoftheobjects,becauseithastomakeacopyofa.
a+=doesnotneedacopy,itisevaluateddirectly.HookedAug12'09at21:49

doesnt"ABCD"[2]resolveto"CD"?ifyouwantittoresolveto'C'youdhavetousedereferencing,i.e. *
("ABCD"[2])=='C') knittl Sep21'09at10:05

No"ABCD"[2]==*("ABCD"+2)=*("CD")='C'.Dereferencingastringgivesyouachar,notasubstring
MSalters Sep21'09at10:34

"It'llbeeasiertoimplementthisway"makesawholelotmoresensethen"mathematicallyitworks,so
eventhoughitservesnopracticalpurposewhatsoever,letsaddittothelanguage"asarational.
DennisZickefooseJun19'11at9:44

Algol68,asfarasIrecall,wastheoriginofcombinedarithmeticandassignationoperators,asin foo+:=
bar ,pronounced'fooplusandbecomesbar'.Ibelievetherationalewasthatthismorecloselyresembled
whatonewantedtodointhefirstplace,namely'addbartofoo'(thoughwhywedidn'tget bar=:+foo
outofthatlogic,Idon'tknow).daveMay3'12at2:26

@ThomasPadronMcCarthy:Fromhere:"Duringdevelopment,[Thompson]continuallystruggledagainst
memorylimitations:eachlanguageadditioninflatedthecompilersoitcouldbarelyfit,buteachrewrite
takingadvantageofthefeaturereduceditssize.Forexample,Bintroducedgeneralizedassignment
operators,usingx=+ytoaddytox...Thompsonwentastepfurtherbyinventingthe++and
operators...astrongermotivationfortheinnovationwasprobablyhisobservationthatthetranslationof
++xwassmallerthanthatofx=x+1."JohnBodeMay3'12at15:19

@dave:It's x+=5; ratherthan x=+5; becausethelatterwouldbeparsedas x=(+5);


JamesCurranJan24'13at14:14

@JamesCurranIamprettysureitstartedoutas LHS=RHS; andwaseventuallyswappedtouse = .


VatineApr18'13at15:58

++frequentlymappedtoasinglemachineinstructionwhilex=x+1couldbemorethanone.x+=3
mapstolessmachineinstructionsthatx=x+3astheknowledgeisthatonewillpickupxonce,add
threetoitanddropitbackdown.registerintx=3isfromthatsameera,whencompilersweren'tassmart
astheyaretoday.EvilTeachOct7'13at2:30

@JamesCurrantheunary + didn'texistinearlyC.MilesRoutJun17'14at15:57

@MilesRout:Perhapsnot,butunaryminusdefinitelydid,leadingtothesameproblem.JamesCurran
Jul1'14at19:22

ThePDP11minicomputer(PDPwereusedforthefirstCandUNIXoperatingsystem)hadassembly
instructionsfor+==++sowhiletheremayhavebeenforerunnersinAlgol,therewereabitof1to1
mappingbetweeninstructionsetandlanguagecapabilities.SorenAug27'14at23:33

@Vatineisright,itwas =+ before += .TheBprogramminglanguage(whichI'msurprisedtoreadisstill


used),ancestorofC,usesthe =+ form.IIRC,themainreasonforchangingitwasthat i=1; was
ambiguous.Notambiguoustothecompiler,buttohumanreaderswhohadtroubleunderstandingwhether
thiswassupposedtodecrease i by1(andhencecorrectlywritten),orwhetherthiswassupposedto
assign 1 to i (andhenceabuginthecode).Disclaimer:myrecollectionmaybefaulty.hvdNov15
'14at12:33

Ithinksomethingisbeingmissedbytheotheranswers.
Yes, p[i] isbydefinitionequivalentto *(p+i) ,which(becauseadditioniscommutative)is
equivalentto *(i+p) ,which(again,bythedefinitionofthe [] operator)isequivalentto i[p] .
(Andin array[i] ,thearraynameisimplicitlyconvertedtoapointertothearray'sfirstelement.)
Butthecommutativityofadditionisnotallthatobviousinthiscase.
Whenbothoperandsareofthesametype,orevenofdifferentnumerictypesthatarepromoted
toacommontype,commutativitymakesperfectsense: x+y==y+x .
Butinthiscasewe'retalkingspecificallyaboutpointerarithmetic,whereoneoperandisapointer
andtheotherisaninteger.(Integer+integerisadifferentoperation,andpointer+pointeris
nonsense.)
TheCstandard'sdescriptionofthe + operator(N15706.5.6)says:
Foraddition,eitherbothoperandsshallhavearithmetictype,oroneoperandshallbeapointer
toacompleteobjecttypeandtheothershallhaveintegertype.

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

4/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

Itcouldjustaseasilyhavesaid:
Foraddition,eitherbothoperandsshallhavearithmetictype,ortheleftoperandshallbea
pointertoacompleteobjecttypeandtherightoperandshallhaveintegertype.
inwhichcaseboth i+p and i[p] wouldbeillegal.
InC++terms,wereallyhavetwosetsofoverloaded + operators,whichcanbeloosely
describedas:
pointeroperator+(pointerp,integeri);

and
pointeroperator+(integeri,pointerp);

ofwhichonlythefirstisreallynecessary.
Sowhyisitthisway?
C++inheritedthisdefinitionfromC,whichgotitfromB(thecommutativityofarrayindexingis
explicitlymentionedinthe1972Users'ReferencetoB),whichgotitfromBCPL(manualdated
1967),whichmaywellhavegottenitfromevenearlierlanguages(CPL?Algol?).
Sotheideathatarrayindexingisdefinedintermsofaddition,andthataddition,evenofapointer
andaninteger,iscommutative,goesbackmanydecades,toC'sancestorlanguages.
ThoselanguagesweremuchlessstronglytypedthanmodernCis.Inparticular,thedistinction
betweenpointersandintegerswasoftenignored.(EarlyCprogrammerssometimesused
pointersasunsignedintegers,beforethe unsigned keywordwasaddedtothelanguage.)Sothe
ideaofmakingadditionnoncommutativebecausetheoperandsareofdifferenttypesprobably
wouldn'thaveoccurredtothedesignersofthoselanguages.Ifauserwantedtoaddtwo"things",
whetherthose"things"areintegers,pointers,orsomethingelse,itwasn'tuptothelanguageto
preventit.
Andovertheyears,anychangetothatrulewouldhavebrokenexistingcode(thoughthe1989
ANSICstandardmighthavebeenagoodopportunity).
ChangingCand/orC++torequireputtingthepointerontheleftandtheintegerontherightmight
breaksomeexistingcode,buttherewouldbenolossofrealexpressivepower.
Sonowwehave arr[3] and 3[arr] meaningexactlythesamething,thoughthelatterform
shouldneverappearoutsidetheIOCCC.
editedMar12at19:49

answeredAug23'13at1:37
KeithThompson
108k

12

126

242

2 Fantasticdescriptionofthisproperty.Fromahighlevelview,Ithink 3[arr] isaninterestingartifactbut


shouldrarelyifeverbeused.Theacceptedanswertothisquestion(< stackoverflow.com/q/1390365/356> )
whichIaskedawhilebackhaschangedthewayI'vethoughtaboutsyntax.Althoughthere'soften
technicallynotarightandwrongwaytodothesethings,thesekindsoffeaturesstartyouthinkinginaway
whichisseparatefromtheimplementationdetails.There'sbenefittothisdifferentwayofthinkingwhichis
inpartlostwhenyoufixateontheimplementationdetails. Dinah Aug24'13at1:01
1 Additioniscommutative.FortheCstandardtodefineitotherwisewouldbestrange.That'swhyitcouldnot
justaseasilysaid"Foraddition,eitherbothoperandsshallhavearithmetictype,ortheleftoperandshallbe
apointertoacompleteobjecttypeandtherightoperandshallhaveintegertype."Thatwouldn'tmake
sensetomostpeoplewhoaddthings.iheanyiApr21'14at17:54
2 @iheanyi:Additionisusuallycommutativeanditusuallytakestwooperandsofthesametype.Pointer
additionletsyouaddapointerandaninteger,butnottwopointers.IMHOthat'salreadyasufficientlyodd
specialcasethatrequiringthepointertobetheleftoperandwouldn'tbeasignificantburden.(Some
languagesuse"+"forstringconcatenationthat'scertainlynotcommutative.)KeithThompsonApr21'14
at18:13
Trueonthestringexample!Inthatlight,thislookslikealanguagedecisionthatcomesfromthe
implementationsideofthingsratherthandesign.iheanyiApr21'14at19:53
@iheanyi:Additionofnumbersiscommutative,butthatdoesn'tmeanthatadditionmustbecommutative
withthingsthatarenotnumbers.Itwasnotuncommonforassemblerstorequirethateveryaddress
involvingarelocatablesymbolmustbeoftheexactform"rel_symbol","rel_symbol+number",or
"rel_symbolnumber",sincethelinkerwouldexpectalistoffixups,eachofwhichidentifieda"base"
symbolandtheplacewhereitwasused(theprefixedupcodewouldholdthenumbertobeaddedtothe
symbol).supercatOct20'14at16:08
@iheanyi:Ithinkit'scleanerfromarulesperspectivetosaythatthesecondoperandofanaddition
operatormustbeanumber,andtheresulttypewillmatchthefirstoperand,thantotrytosaythat"atleast
one"operandmustbeanumber.Incidentally,alotofannoyancesrelatedtounsignedtypescouldhave
beeneliminatediftheadditionoperatoralwaysreturnedthetypeofitslefthandoperand,ratherthansaying
thatgiven uint32_tx=0; thevalueof x1 mustonsomeimplementationsyield4294967295andon
othersyield1.supercatOct20'14at16:18
1 @supercat,That'sevenworse.Thatwouldmeanthatsometimesx+1!=1+x.Thatwouldcompletely
violatetheassociativepropertyofaddition.iheanyiOct21'14at16:34
1 @iheanyi:Ithinkyoumeantcommutativepropertyadditionisalreadynotassociative,sinceonmost

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

5/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

implementations(1LL+1U)2!=1LL+(1U2).Indeed,thechangewouldmakesomesituationsassociative
whichpresentlyaren't,e.g.3U+(UINT_MAX2L)wouldequal(3U+UINT_MAX)2.Whatwouldbebest,
though,isforthelanguagetohaveaddnewdistincttypesforpromotableintegersand"wrapping"algebraic
rings,sothatadding2toa ring16_t whichholds65535wouldyielda ring16_t withvalue1,
independentofthesizeof int .supercatOct21'14at16:46
@supercatthanksforthatresponse.Thatclarifiestheissuesathandwithagoodexample:)iheanyi
Oct21'14at16:59
Thatistherightanswer!JeanBaptisteYuns Nov18'14at8:20

OnethingnooneseemstohavementionedaboutDinah'sproblemwith sizeof :
Youcanonlyaddanintegertoapointer,youcan'taddtwopointerstogether.Thatwaywhen
addingapointertoaninteger,oranintegertoapointer,thecompileralwaysknowswhichbithas
asizethatneedstobetakenintoaccount.
editedDec18'09at8:01

answeredFeb11'09at15:56

Dinah
17.4k

user30364
22

95

124

414

There'safairlyexhaustiveconversationaboutthisinthecommentsoftheacceptedanswer.Ireferenced
saidconversationintheedittotheoriginalquestionbutdidnotdirectlyaddressyourveryvalidconcernof
sizeof.NotsurehowtobestdothisinSO.ShouldImakeanotheredittotheorig.question? Dinah Apr
21'09at13:51

Toanswerthequestionliterally.Itisnotalwaystruethat x==x
doublezero=0.0;
doublea[]={0,0,0,0,0,zero/zero};//NaN
cout<<(a[5]==5[a]?"true":"false")<<endl;

prints
false

answeredAug11'11at13:50
PeterLawrey
267k

28

266

519

15 Actuallya"nan"isnotequaltoitself: cout<<(a[5]==a[5]?"true":"false")<<endl; is
false . TrueY Apr23'13at9:34
1

@TrueY:HedidstatethatspecificallyfortheNaNcase(andspecificallythat x==x isnotalwaystrue).


Ithinkthatwashisintention.Soheistechnically correct(andpossibly,astheysay,thebestkindof
correct!).Timas Feb13at1:04

Nicequestion/answers.
JustwanttopointoutthatCpointersandarraysarenotthesame,althoughinthiscasethe
differenceisnotessential.
Considerthefollowingdeclarations:
inta[10];
int*p=a;

Ina.out,thesymbolaisatanaddressthat'sthebeginningofthearray,andsymbolpisatan
addresswhereapointerisstored,andthevalueofthepointeratthatmemorylocationisthe
beginningofthearray.
answeredDec20'08at8:16
PolyThinker
3,673

11

20

2 No,technicallytheyarenotthesame.Ifyoudefinesomebasint*constandmakeitpointtoanarray,itis
stillapointer,meaningthatinthesymboltable,breferstoamemorylocationthatstoresanaddress,
whichinturnpointstowherethearrayis.PolyThinkerDec22'08at5:42
2 Verygoodpoint.IrememberhavingaverynastybugwhenIdefinedaglobalsymbolaschars[100]inone
module,declareitasexternchar*sinanothermodule.Afterlinkingitalltogethertheprogrambehaved
verystrangely.Becausethemoduleusingtheexterndeclarationwasusingtheinitialbytesofthearrayas
apointertochar.GiorgioMay2'12at18:15
Originally,inC'sgrandparentBCPL,anarraywasapointer.Thatis,whatyougotwhenyouwrote(Ihave
transliteratedtoC) inta[10] wasapointercalled'a',whichpointedtoenoughstorefor10integers,
elsewhere.Thusa+iandj+ihadthesameform:addthecontentsofacoupleofmemorylocations.Infact,
IthinkBCPLwastypeless,sotheywereidentical.Andthesizeoftypescalingdidnotapply,sinceBCPL
waspurelywordoriented(onwordaddressedmachinesalso).daveMay3'12at2:33

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

6/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

Ithinkthebestwaytounderstandthedifferenceistocompare int*p=a; to intb=5; Inthelatter,


"b"and"5"arebothintegers,but"b"isavariable,while"5"isafixedvalue.Similarly,"p"&"a"areboth
addressesofacharacter,but"a"isafixedvalue.JamesCurranMar12'13at16:34

ForpointersinC,wehave
a[5]==*(a+5)

andalso
5[a]==*(5+a)

Henceitistruethat a[5]==5[a].
editedMar23'12at17:36
user1055604
1,044

answeredMar23'12at7:05
user1287577

20

Ijustfindoutthisuglysyntaxcouldbe"useful",oratleastveryfuntoplaywithwhenyouwantto
dealwithanarrayofindexeswhichrefertopositionsintothesamearray.Itcanreplacenested
squarebracketsandmakethecodemorereadable!
inta[]={2,3,3,2,4};
ints=sizeofa/sizeof*a;//s==5
for(inti=0;i<s;++i){
cout<<a[a[a[i]]]<<endl;
//...isequivalentto...
cout<<i[a][a][a]<<endl;//butIpreferthisone,it'seasiertoincrease
thelevelofindirection(withoutloop)
}

Ofcourse,I'mquitesurethatthereisnousecaseforthatinrealcode,butIfounditinteresting
anyway:)
answeredJun10'12at19:50
FrdricTerrazzoni
1,010

16

1 OhGod!!!howcansomebodysaythatprefersthatnotation!!!Ithurtsmyeyes!!!LuisColoradoSep19
'14at13:14

Notananswer,butjustsomefoodforthought.Ifclassishavingoverloadedindex/subscript
operator,the0[x]willnotwork:
classSub
{
public:
intoperator[](size_tnIndex)
{
return0;
}
};
intmain()
{
Subs;
s[0];
0[s];//ERROR
}

Sincewedonthaveaccesstointclass,thiscannotbedone:
classint
{
intoperator[](constSub&);
};

answeredJun19'11at8:37
Ajay
7,050

15

44

1 classSub{public:intoperator[](size_tnIndex)const{return0;}friendintoperator[]
(size_tnIndex,constSub&This){return0;}}; BenVoigt Apr5'13at17:23
Haveyouactuallytriedcompilingit?Therearesetofoperatorsthatcannotbeimplementedoutsideclass
(i.e.asnonstaticfunctions)!Ajay Apr5'13at21:10

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

7/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

oops,you'reright." operator[] shallbeanonstaticmemberfunctionwithexactlyoneparameter."Iwas


familiarwiththatrestrictionon operator= ,didn'tthinkitappliedto [] .BenVoigtApr5'13at21:21
Ofcourse,ifyouchangethedefinitionof [] operator,itwouldneverbeequivalentagain...if a[b] is
equalto *(a+b) andyouchangethis,you'llhavetooverloadalso int::operator[](constSub&); and
int isnotaclass... LuisColorado Sep19'14at13:18

IthasverygoodexplanationinATUTORIALONPOINTERSANDARRAYSINCbyTed
Jensen

TedJensenexplaineditas:

Infact,thisistrue,i.ewhereveronewrites a[i] itcanbereplacedwith *(a+i) withoutany


problems.Infact,thecompilerwillcreatethesamecodeineithercase.Thusweseethatpointer
arithmeticisthesamethingasarrayindexing.Eithersyntaxproducesthesameresult.
ThisisNOTsayingthatpointersandarraysarethesamething,theyarenot.Weareonlysaying
thattoidentifyagivenelementofanarraywehavethechoiceoftwosyntaxes,oneusingarray
indexingandtheotherusingpointerarithmetic,whichyieldidenticalresults.
Now,lookingatthislastexpression,partofit.. (a+i) ,isasimpleadditionusingthe+operator
andtherulesofCstatethatsuchanexpressioniscommutative.Thatis(a+i)isidenticalto (i
+a) .Thuswecouldwrite *(i+a) justaseasilyas *(a+i) .
But *(i+a) couldhavecomefrom i[a] !Fromallofthiscomesthecurioustruththatif:
chara[20];

writing
a[3]='x';

isthesameaswriting
3[a]='x';

answeredSep27'13at6:46
A.s.Bhullar
577

14

Onlyifyoucame5yearsearlier!chouaibJul18'14at2:05
@chouaibyesthatswhyIaskedthis question:)A.s.BhullarJul18'14at9:03

InCarrays , arr[3] and 3[arr] arethesame,andtheirequivalentpointernotationsare *(arr+


3) to *(3+arr) .Butonthecontrary [arr]3 or [3]arr isnotcorrectandwillresultintosyntax
error,as (arr+3)* and (3+arr)* arenotvalidexpressions.Thereasonisdereference
operatorshouldbeplacedbeforetheaddressyieldedbytheexpression,notaftertheaddress.
answeredDec17'13at11:22
Krishan
69

inccompiler
a[i]
i[a]
*(a+i)

aredifferentwaystorefertoanelementinanarray!(NOTATALLWEIRD)
answeredOct29'14at9:14
AVIKDUTTA
435

15

5[a]seemsweirdtomethough.Dronz Mar12at19:44

protectedbyCommunity May18'13at13:13
Thankyouforyourinterestinthisquestion.Becauseithasattractedlowqualityanswers,postingananswernowrequires10reputationonthissite.
Wouldyouliketoansweroneoftheseunansweredquestions instead?

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

8/9

5/13/2015

WithCarrays,whyisitthecasethata[5]==5[a]?StackOverflow

http://stackoverflow.com/questions/381542/withcarrayswhyisitthecasethata55a/18393343#18393343

9/9

You might also like