Hi Hervé, Glad you enjoyed the slides :)
Here's a bit more material discussing why 'i = ++i' and friends are actually defined under the C++11 standard, but undefined before: Why it might be well-defined in C++0x and above: http://stackoverflow.com/questions/3852768/unsequenced-value-computations-a-k-a-sequence-points Why i = i++ is undefined, and i = ++i is defined, for C++0x and above: http://stackoverflow.com/questions/17400137/order-of-evaluation-and-undefined-behaviour http://stackoverflow.com/questions/3690141/multiple-preincrement-operations-on-a-variable-in-cc/3691469#3691469 I would imagine this would translate into a similar undefined-ness for the C standards, but would not be surprised if I were wrong... IIUC, though, using the rules that 1. A variable may only be modified once between two sequence points, and 2. 'i = ++i' modifies 'i' twice without a sequence point to separate them means it's undefined there. IIUC (and I may not), precedence doesn't even play in here -- if we modify a variable twice between two sequence points, we have UB. Anyway, I think I've gone too far down the rabbit hole into the language lawyer land of C/C++ standards, so let's all just agree that, regardless of what the correct interpretation is, 'i = i++' and 'i = ++i' are just things you shouldn't write :) Cheers, Kevin On Tue, Jun 24, 2014 at 3:38 PM, Hervé Pagès <hpa...@fhcrc.org> wrote: > Hi Kevin, > > > On 06/23/2014 10:28 PM, Kevin Ushey wrote: > >> I don't see what's so surprising here. >> >> That statement is identical to writing: >> >> if (arrMask[i] == 1) { >> numsels = ++numsels; >> } else { >> numsels = numsels; >> } >> >> and >> >> numsels = ++numsels; >> >> has two statements modifying the value of numsels (= and prefix-++) in >> a single sequence point. (Do we increment then assign, or assign then >> increment? The C / C++ standards leave this undefined.) >> >> Imagine writing the operations out as functions: we have the `=` >> function, and the `prefix-++` function -- both of these 'mo dify' (one >> >> of) their arguments. Do we evaluate it as `=`(a, `prefix-++`(a)) or >> `prefix-++`(`=`(a, a))? >> > > As the former? Isn't it that `prefix-++` has precedence over `=`? Also > according to the standard, `prefix-++` must perform the increment > *before* returning the incremented value. So I'm still a little bit > confused about this warning. Although I would understand it if > `suffix-++` was used instead of `prefix-++`: > > numsels = numsels++; > > In that case the incrementation happens *after* the right value > of the assignment is evaluated but it's undefined whether it will > happen before or after the assignment itself (on my machine it > happens after). > > > The C standard leaves this undefined, so >> compilers are free to do what they wish (and the nice ones warn you >> when there is such an ambiguity). I guess the net result of the >> operation is the same in each case _here_, but this is of course not >> the case for other functions that modify the value of their >> operand(s). And, in truth, this is _undefined behaviour_ and so the >> compiler could still rightly make demons fly out of your nose if it >> wanted to upon program execution. >> >> I highly recommend reading the slides at >> http://www.slideshare.net/olvemaudal/deep-c, especially the bit on >> sequence points. >> > > Nice slides. Pretty entertaining! The numsels = numsels++ case is > actually discussed at slide 142. Thanks for the link! > > > H. > > >> Cheers, >> Kevin >> >> On Mon, Jun 23, 2014 at 9:22 PM, Kasper Daniel Hansen >> <kasperdanielhan...@gmail.com> wrote: >> >>> I am not an expert on this, but I note that the section on >>> -Wsequence-point >>> at >>> http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html >>> specifically mentions ? and :. Perhaps some more work on tracking down >>> their definitions and precedence might lead to insights. >>> >>> Best, >>> Kasper >>> >>> >>> On Mon, Jun 23, 2014 at 6:42 PM, Hervé Pagès <hpa...@fhcrc.org> wrote: >>> >>> On 06/23/2014 03:18 PM, Hervé Pagès wrote: >>>> >>>> Hi Christian, >>>>> >>>>> On 06/23/2014 11:54 AM, cstrato wrote: >>>>> >>>>> Dear Romain, >>>>>> >>>>>> I do not know enough about compilers, but as far as I remember, they >>>>>> 'work' from right to left, >>>>>> >>>>>> >>>>> Not necessarily. So you should not rely on that. This is what the >>>>> (somewhat obscure) warning you see on zin1 is trying to tell you. >>>>> >>>>> >>>> Actually, I don't see an ambiguity in your code: >>>> >>>> >>>> numsels = (arrMask[i] == 1) ? ++numsels : numsels; >>>> >>>> Yes it's confusing and unnecessarily complicated but I don't see that >>>> it relies on some undefined behavior. It's not like in the thread on >>>> Bioc-devel where the expression was: >>>> >>>> *p++ = tolower(*p); >>>> >>>> In that case the left-value of the assignment is itself an expression >>>> that needs to be evaluated and the outcome of the assignment depends >>>> on whether the left-value is evaluated before the right expression or >>>> not. But in your case the left-value is a variable name so there is >>>> nothing to evaluate. >>>> >>>> So I don't know. Looks like a false positive from the gcc compiler to >>>> me. Someone on the list might have a better insight. >>>> >>>> Cheers, >>>> >>>> H. >>>> >>>> >>>> Personally I would just do: >>>> >>>>> >>>>> if (arrMask[i] == 1) numsels++; >>>>> >>>>> which is the standard way to implement the "if (some condition) >>>>> then increment counter" idiom. >>>>> >>>>> As Kasper mentioned, a similar issue was recently discussed here: >>>>> >>>>> https://stat.ethz.ch/pipermail/bioc-devel/2014-June/005858.html >>>>> >>>>> Cheers, >>>>> H. >>>>> >>>>> >>>>> so numsels = ++numsels should not confuse the >>>>> >>>>>> compiler. Anyhow I will change my code to your first suggestion since >>>>>> it >>>>>> is more elegant. >>>>>> >>>>>> Best regards, >>>>>> Christian >>>>>> >>>>>> >>>>>> On 6/23/14 7:13 PM, Romain François wrote: >>>>>> >>>>>> >>>>>>> Le 23 juin 2014 à 18:28, cstrato <cstr...@aon.at> a écrit : >>>>>>> >>>>>>> Dear Romain, >>>>>>> >>>>>>>> >>>>>>>> Thank you for your suggestions, I like especially the first one. >>>>>>>> >>>>>>>> However, you did not explain why I have never got this warning >>>>>>>> message on any compiler, and why only one of the two identical >>>>>>>> Ubuntu >>>>>>>> compilers did give this warning message? >>>>>>>> >>>>>>>> Best regards, >>>>>>>> Christian >>>>>>>> >>>>>>>> >>>>>>> I donât know, but this: >>>>>>> >>>>>>> numsels = ++numsels ; >>>>>>> >>>>>>> seems fishy to me, and so it keeps feeling weird with the addition of >>>>>>> the ternary operator. >>>>>>> >>>>>>> There is obviously a difference of setup between these two machines, >>>>>>> but I donât have time to sherlock that for you. One of the compilers >>>>>>> is getting more careful than the other. Getting warnings you did not >>>>>>> get before is a good thing, as it helps you update the code with that >>>>>>> new insight. >>>>>>> >>>>>>> Welcome to my world, Iâm sometimes thrown all kinds of new warnings >>>>>>> from esoteric compilers, all of them have value . >>>>>>> >>>>>>> Romain >>>>>>> >>>>>>> On 6/23/14 3:45 PM, Romain François wrote: >>>>>>> >>>>>>>> >>>>>>>> >>>>>>>>> Le 23 juin 2014 à 15:20, cstrato <cstr...@aon.at> a écrit : >>>>>>>>> >>>>>>>>> Dear all, >>>>>>>>> >>>>>>>>>> >>>>>>>>>> Since many years the following C++ code does compile on ALL >>>>>>>>>> Bioconductor servers (Linux, Windows, Mac) without any warnings: >>>>>>>>>> >>>>>>>>>> Int_t numsels = 0; //number of selected entries >>>>>>>>>> ... >>>>>>>>>> for (Int_t i=0; i<size; i++) { >>>>>>>>>> numsels = (arrMask[i] == 1) ? ++numsels : numsels; >>>>>>>>>> }//for_i >>>>>>>>>> >>>>>>>>>> >>>>>>>>> This is confusing. I would write the loop body like this: >>>>>>>>> >>>>>>>>> numsels += (arrMask[i] == 1) ; >>>>>>>>> >>>>>>>>> >>>>>>>>> or preferably using the STL: >>>>>>>>> >>>>>>>>> Int_t numsels = std::count( begin(arrMask), end(arrMask), 1 ) ; >>>>>>>>> >>>>>>>>> or some other variation of this, i.e. perhaps you donât have a >>>>>>>>> C++11 >>>>>>>>> compiler, so perhaps one of these depending on what is arrMask: >>>>>>>>> >>>>>>>>> Int_t numsels = std::count( arrMask.begin(), arrMask.end(), 1 ) ; >>>>>>>>> Int_t numsels = std::count( arrMask, arrMask + size, 1 ) ; >>>>>>>>> >>>>>>>>> Romain >>>>>>>>> >>>>>>>>> Even on the recently added release server 'zin2' Linux (Ubuntu >>>>>>>>> >>>>>>>>>> 12.04.4 LTS) the above code compiles w/o warnings. >>>>>>>>>> >>>>>>>>>> However, on the new development server 'zin1' Linux (Ubuntu >>>>>>>>>> 12.04.4 >>>>>>>>>> LTS) I get suddenly the following warning message: >>>>>>>>>> >>>>>>>>>> Found the following significant warnings: >>>>>>>>>> XPSPreProcessing.cxx:3026:56: warning: operation on ânumselsâ >>>>>>>>>> may >>>>>>>>>> be undefined [-Wsequence-point] >>>>>>>>>> >>>>>>>>>> Interestingly, both servers do not only run the same version of >>>>>>>>>> Ubuntu, but also the same version of the C++ compiler, i.e. g++ >>>>>>>>>> (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, and use the same flags, see: >>>>>>>>>> http://bioconductor.org/checkResults/2.14/bioc-LATEST/ >>>>>>>>>> zin2-NodeInfo.html >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> http://bioconductor.org/checkResults/devel/bioc- >>>>>>>>>> LATEST/zin1-NodeInfo.html >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> My question is now, why do I suddenly get the compiler warning? >>>>>>>>>> >>>>>>>>>> The reason why I ask at R-devel and not Bioc-devel is that it may >>>>>>>>>> not only be a Bioc question, since I found the following links: >>>>>>>>>> http://c-faq.com/expr/seqpoints.html >>>>>>>>>> http://stackoverflow.com/questions/16838884/why-i-got- >>>>>>>>>> operation-may-be-undefined-in-statement-expression-in-c >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> I am not sure if I understand the meaning, but until now I have >>>>>>>>>> never got any warning from any compiler the I have used (including >>>>>>>>>> MS Visual C++). >>>>>>>>>> >>>>>>>>>> Do I really have to replace '++numsels' with 'numsels+1'? >>>>>>>>>> >>>>>>>>>> Best regards, >>>>>>>>>> Christian >>>>>>>>>> _._._._._._._._._._._._._._._._._._ >>>>>>>>>> C.h.r.i.s.t.i.a.n S.t.r.a.t.o.w.a >>>>>>>>>> V.i.e.n.n.a A.u.s.t.r.i.a >>>>>>>>>> e.m.a.i.l: cstrato at aon.at >>>>>>>>>> _._._._._._._._._._._._._._._._._._ >>>>>>>>>> >>>>>>>>>> ______________________________________________ >>>>>>>>>> R-devel@r-project.org mailing list >>>>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>> >>>>>>> ______________________________________________ >>>>>> R-devel@r-project.org mailing list >>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel >>>>>> >>>>>> >>>>> >>>>> -- >>>> Hervé Pagès >>>> >>>> Program in Computational Biology >>>> Division of Public Health Sciences >>>> Fred Hutchinson Cancer Research Center >>>> 1100 Fairview Ave. N, M1-B514 >>>> P.O. Box 19024 >>>> Seattle, WA 98109-1024 >>>> >>>> E-mail: hpa...@fhcrc.org >>>> Phone: (206) 667-5791 >>>> Fax: (206) 667-1319 >>>> >>>> ______________________________________________ >>>> R-devel@r-project.org mailing list >>>> https://stat.ethz.ch/mailman/listinfo/r-devel >>>> >>>> >>> [[alternative HTML version deleted]] >>> >>> >>> ______________________________________________ >>> R-devel@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >>> > -- > Hervé Pagès > > Program in Computational Biology > Division of Public Health Sciences > Fred Hutchinson Cancer Research Center > 1100 Fairview Ave. N, M1-B514 > P.O. Box 19024 > Seattle, WA 98109-1024 > > E-mail: hpa...@fhcrc.org > Phone: (206) 667-5791 > Fax: (206) 667-1319 > [[alternative HTML version deleted]]
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel