bugGNU Octave - Bugs: bug #51962, "A++" assigns to 'ans'...


bug #51962: "A++" assigns to 'ans' while "A += 1" and "A = A + 1" do not

Submitter:  None
Submitted:  Fri 08 Sep 2017 02:46:10 AM UTC
Category:  Interpreter Severity:  3 - Normal
Priority:  3 - Low Item Group:  Performance
Status:  None Assigned to:  None
Originator Name:  Originator Email:  -email is unavailable-
Open/Closed:  * Open Release:  * 4.2.1
Operating System:  * Any Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup

Jump to the original submission

Sun 10 Sep 2017 07:16:09 PM UTC, comment #11: 

Definitely worth documenting!
Maybe even include your example.

Michael Godfrey <godfrey>
Group Member
Sun 10 Sep 2017 06:47:16 PM UTC, comment #10: 

That's what I was suggesting in comment #2, if there is a way to determine that the "A++" expression would not be assigned to some other value and suppress the extra copy of A made. I'm not sure that's possible, but worth looking into.

It occurred to me that it's also worth documenting that "++A" is more efficient than "A++". The prefix operator does not need to create an extra copy of A. In C++ terms this is often mentioned to avoid making unnecessary expensive copies of objects. In Octave this should be mentioned because it avoids making expensive copies of large arrays due to Octave's COW behavior.

>> A = rand (1e4);  ## Octave allocates 800 MB
>> ++A;  ## A incremented, ans == A, no extra memory used
>> A++;  ## A incremented, ans != A, 1600 MB now used

Mike Miller <mtmiller>
Group Member
Sun 10 Sep 2017 04:08:32 AM UTC, comment #9: 

I had more in mind lazy evaluation so that the pre- and postfix timing was still respected, but that the actual operation was performed by the in-place operator.

C doesn't have an 'ans' variable and Matlab doesn't have '++'/'--' operators so there is no compatibility requirements that say we couldn't make these operators do somethin special, like not return the ans variable.

But I'm also not too bothered if we just want to document the difference.

Rik <rik5>
Group administrator
Sat 09 Sep 2017 09:43:08 PM UTC, comment #8: 

Good point.
That convinces me to agree to leave behavior as it is,
and do the documentation.

Michael Godfrey <godfrey>
Group Member
Sat 09 Sep 2017 08:22:30 PM UTC, comment #7: 

IMHO redoing the ++ and -- operators to be the same thing as +=1 and -=1 would not be a good thing and would break some behavior. The ++ and -- operators currently mimic the C prefix and postfix behavior, which to me is a good and intentional thing worth keeping.

Specifically, the following postfix behavior would change

>> x = 1;
>> y = x++;
x, y
x =  2
y =  1
>> x = 1;
>> y = (x += 1);
x, y
x =  2
y =  2

I think it would be better to fully document the differences, that "X += 1" only affects X, while "X++" affects X and also returns a copy of the previous value of X as a side effect, which may take up a lot of memory depending on the size of X.

Mike Miller <mtmiller>
Group Member
Sat 09 Sep 2017 05:54:14 PM UTC, comment #6: 

Rik: Your suggestion seems good. Saves 2 operators,
and avoids excess memory use.

John may have a view.

Michael Godfrey <godfrey>
Group Member
Sat 09 Sep 2017 05:36:38 PM UTC, comment #5: 

Another possibiliy would be to make the ++ and -- operators be syntatic sugar for += 1 and -= 1.  Currently I believe they are recognized by the parser and mapped on to their own operators.

Rik <rik5>
Group administrator
Fri 08 Sep 2017 05:41:13 PM UTC, comment #4: 

It would be fairly easy to provide a global option to disable the use of the "ans" variable to track the last result that is computed but not assigned.

John W. Eaton <jwe>
Group administrator
Fri 08 Sep 2017 05:40:31 PM UTC, comment #3: 

I re-titled the bug report, but yes, this is ordinary and expected Octave behavior.  Whenever you execute an operation, for which no variable is assigned, then the default variable 'ans' gets the output.

The easy workaround, as mentioned, is to use assignment so that 'ans' is not created.  Alternatively, you could look at using a different algorithm that doesn't use so much memory.  If your matrices are large, but mostly 0 elements, then use sparse arrays.  And as a last resort, just run on a machine with more memory.

Rik <rik5>
Group administrator
Fri 08 Sep 2017 05:12:25 PM UTC, comment #2: 

I don't see how this can be changed honestly.

A++ is an expression that modifies the value of A and also returns a value that is different from the value of A. It must always have a side effect returning a value different from the operand, so where else but 'ans' should that value go?

The only possible way this could work would be to determine if this expression is the top-level expression in a statement and if there is no lvalue, then suppress returning a copy of A. But that doesn't sound reasonable to me.

Mike Miller <mtmiller>
Group Member
Fri 08 Sep 2017 03:26:02 PM UTC, comment #1: 

Actually, for maximal performance use

A += 1
A -= 1

In-place operators have been optimized so that a second copy is never created.  Even

A = A + 1

is not guaranteed not to create a temporary matrix.  Octave may, and most likely will, do

tmp = A + 1;
A = tmp;

for "A = A + 1".

The increment and decrement operators should map on to the in-place operators, but they don't yet.

I'm lowering the severity because there is a simple work-around of using += or -= operators.

Rik <rik5>
Group administrator
Fri 08 Sep 2017 02:46:10 AM UTC, original submission:  

A = a very large matrix.
# code here to build A

# run out of memory soon
A    (large amount of memory)
ans  (same large amount of memory)

Enough memory for A but not both A and ans simultaneously.


A = A+1; does not cause ans to become same as A.
Even A = A++; does not cause memory use to double.

Unexpected behavior because of side-effects in copying A to ans.

Side-effect behavior of ++ and -- may need to be changed to not update ans.



(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by godfrey (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.


    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-09-08 rik5 Summary++ and -- not same as +1 and -1 "A++" assigns to 'ans' while "A += 1" and "A = A + 1" do not
    2017-09-08 jwe Summary&quot;A++&quot; assigns to 'ans' while &quot;A += 1&quot; and &quot;A = A + 1&quot; do not ++ and -- not same as +1 and -1
    2017-09-08 rik5 Summary++ and -- not same as +1 and -1 "A++" assigns to 'ans' while "A += 1" and "A = A + 1" do not
    2017-09-08 rik5 CategoryNone Interpreter
        Priority5 - Normal 3 - Low
        Item GroupUnexpected Error or Warning Performance
        Operating SystemMicrosoft Windows Any

    Back to the top

    Powered by Savane 3.13-4b48.
    Corresponding source code