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 <hpages@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
>> <kasperdanielhansen@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 <hpages@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 <cstrato@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 <cstrato@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: hpages@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: hpages@fhcrc.org
> Phone:  (206) 667-5791
> Fax:    (206) 667-1319
>

	[[alternative HTML version deleted]]

