bugGNU Octave - Bugs: bug #67403, numArgumentsFromSubscript...

 
 

bug #67403: numArgumentsFromSubscript incorrectly called in assignment of susbsref expression

Submitter:  Fernando <tutissanalio>
Submitted:  Thu 07 Aug 2025 10:30:37 AM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Ready For Test Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  11.1.0 (current default)
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Thu 14 Aug 2025 07:14:32 AM UTC, comment #11: 

Thank you for the follow-ups.

I agree that Matlab's behavior when it comes to the value of nargout while being called from within brackets is odd. Maybe, it is more consistent to keep Octave's current behavior and intentionally deviate from Matlab (at least until we find a use-case that explains why Matlab is behaving like that).

I pushed your patch (with only very minor changes) to the default branch:
https://hg.savann ... /rev/15b1933b91ce

Marking as ready for test.

Markus Mützel <mmuetzel>
Group administrator
Wed 13 Aug 2025 06:37:44 AM UTC, comment #10: 

I realized the subsref method of the test class can be simplified a little with this change:

--- a/test/bug-67403/class_bug67403.m   Sun Aug 10 11:13:51 2025 +0200
+++ b/test/bug-67403/class_bug67403.m   Wed Aug 13 08:33:11 2025 +0200
@@ -1,8 +1,7 @@
 classdef class_bug67403
   methods
     function [varargout] = subsref (obj, s)
-      varargout = cell(1, max(nargout,1));
-      varargout(:) = {nargout};
+      varargout = num2cell (repelem(nargout, max(nargout,1)));
     endfunction
     function n = numArgumentsFromSubscript(obj,s,indexingContext)
       n = 2;

I can modify the patch if you want. I can also modify the class so that it is syntax-compatible with Matlab (easier to quicly test with Matlab).

Fernando <tutissanalio>
Tue 12 Aug 2025 07:21:06 PM UTC, comment #9: 

Thanks for your comments. I also noticed that difference between Matlab and Octave in things like [obj(1)], but I think it is unrelated to this part of code. To change that, we would need to change the value of the input nargout of the subsref function, so that it is 0 instead of -1 in expressions like [obj(1)]. Also note that in Matlab you have:

>> [obj(1)]
ans =
     0
>> [obj(1), obj(1)]
ans =
     1     1


I'm not sure why, and if it is important for Octave to mimic that. In any case, I think it should be a separate bug report.

Fernando <tutissanalio>
Tue 12 Aug 2025 05:11:01 PM UTC, comment #8: 

Thank you for clarifying. That makes sense.

I experimented a bit with the class from your new test and compared various indexing expressions between Octave and Matlab. (I only changed to compatible syntax in class_bug67403_2, otherwise it is the same as class_bug67403.)
Most of them behave the same. 👍

One expression differs between the two.
In Octave (with your patch applied):

octave:2> obj = class_bug67403_2();
octave:3> obj(1)
ans = 0
octave:4> [obj(1)]
ans = 1
octave:5>


In Matlab R2024b:

>> obj = class_bug67403_2();
>> obj(1)

ans =

     0

>> [obj(1)]

ans =

     0


In Octave, the value of `nargout` seems to be 1 if the expression is enclosed in brackets. It is 0 without the brackets.
In Matlab, it is always 0 independent on whether there are surrounding brackets or not.

I don't know if this is related to the part of the code that you are changing. (It might not be.)
But you are deeper into that part of the code currently. Could that be addressed here, too? Or better in a different bug report?

Other than that, the patch looks good to me.
Being able to get rid of that complicated expression for `maybe_cs_list_query` looks like a step in the right direction. 👍

Markus Mützel <mmuetzel>
Group administrator
Tue 12 Aug 2025 10:39:38 AM UTC, comment #7: 

@Markus:
If I am not wrong, in general, applying a ()-index to a function handle only produces a cs-list if the call is the right-hand side of a multiple assignment, e.g. [a,b]=f(x), (the same as calling a function). Otherwise, only the first element of the returned cs-list is taken and the rest is discarded.
So, I think function handles require no special treatment here.

Rewriting and expanding part of comment #4, Matlab seems to call numArgumentsFromSubscript only when all the following conditions are true:
- the classdef has a subsref method.
- the susbsref operation is not the right-hand side of an assigment.
- the last index of the subsref operation is not a ()-index.
- of course, the classdef has a numArgumentsFromSubscript method.

Fernando <tutissanalio>
Tue 12 Aug 2025 07:06:26 AM UTC, comment #6: 

I haven't come around to taking a deeper look at your proposed change yet.

Just asking reading what you described here: In this context, could a ()-index produce a cs-list if the "object" (likely the value of a property?) that it is "indexing" is a function handle? Do we need to take that into consideration here?

Markus Mützel <mmuetzel>
Group administrator
Sun 10 Aug 2025 09:22:29 AM UTC, comment #5: 

Oops, I forgot to eliminate a test class that is not being used.

(file #57516)

Fernando <tutissanalio>
Sat 09 Aug 2025 04:23:43 PM UTC, comment #4: 

After trying different examples (see test/bug-67403/bug-67403.tst), I come to the conclusion that Matlab does not call numArgumentsFromSubscript if either:
- the subsref operation is the right-hand-side of an assignment
- or the last index of the subsref is of type '()'. This makes sense because a ()-index should not produce a cs-list.

Taking that into account, I propose the attached patch. I replaced the variable maybe_cs_list_query

              bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{'
                                          || (type.length () > 1 && type[0] == '('
                                              && type[1] == '.'));

by the simpler condition

type.back () != '('


(file #57513)

Fernando <tutissanalio>
Fri 08 Aug 2025 12:16:04 PM UTC, comment #3: 

I didn't get it right. There's another situation in which a subsref operation does not need to call numArgumentsFromSubscript. To see it more clearly, I modified slightly the class from comment #1, like this:

classdef class_subsref2
  methods
    function [a, b, c] = subsref (obj, s)
      a = 1;
      b = 2;
      c = 3;
    end
    function n = numArgumentsFromSubscript(obj,s,indexingContext)
      fprintf('numArgumentsFromSubscript called\n')
      n = 2;
    end
  end
end

The class is attached. Then, in Matlab (2024b), I get:

>> obj = class_subsref2;
>> obj(1)
ans =
     1
>> obj{1}
numArgumentsFromSubscript called
ans =
     1
ans =
     2
>> obj.a
numArgumentsFromSubscript called
ans =
     1
ans =
     2

Thus, a subsref operation with parenthesis "()" only need not call numArgumentsFromSubscript, because it returns a single output (unless the result is being assigned to multiple variables, in which case the number of outputs should match the number of variables assigned).

I will modify the patch.

(file #57508)

Fernando <tutissanalio>
Thu 07 Aug 2025 09:03:33 PM UTC, comment #2: 

A slight modification of the test in the patch, to check that numArgumentsFromSubscript is actually called if there is no assignment.

(file #57507)

Fernando <tutissanalio>
Thu 07 Aug 2025 07:10:41 PM UTC, comment #1: 

See attached file for a patch, including a test.

(file #57506)

Fernando <tutissanalio>
Thu 07 Aug 2025 10:30:37 AM UTC, original submission:  

With the attached file class_subsref.m, I get:

octave:1> obj = class_subsref;
octave:2> [a,b,c] = obj(1)
numArgumentsFromSubscript called
a = 1
error: element number 2 undefined in return list

However, in Matlab (R2024b), I get:

>> obj = class_subsref;
>> [a,b,c] = obj(1)
a =
     1
b =
     2
c =
     3


This has to do with the function numArgumentsFromSubscript, which was introduced in https://hg.savann ... /rev/21a9e15bcb54 (bug #65876).

Apparently, if there is an assignment of a subsref expression, Matlab does not call numArgumentsFromSubscript, it just takes the number of lvalues as the number of outputs of the subsref operation.

In the example class, numArgumentsFromSubscript is incorrect, but it should not affect.

Fernando <tutissanalio>

 

Attached Files

Attached Files
file #57516:  bug67403-4.cset added by tutissanalio (6.5KiB - application/octet-stream)
file #57513:  bug67403-3.cset added by tutissanalio (6.9KiB - application/octet-stream)
file #57508:  class_subsref2.m added by tutissanalio (272B - text/x-objcsrc)
file #57507:  bug67403-2.cset added by tutissanalio (6.3KiB - application/octet-stream)
file #57506:  bug67403.cset added by tutissanalio (6.3KiB - application/octet-stream)
file #57505:  class_subsref.m added by tutissanalio (271B - text/x-objcsrc)

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

Attach Files:
   
   
Comment:
   

 

Dependencies

This item does not depend on any other items.

No items depend on this one.

 

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by tutissanalio (Submitted the item)
  •  

    Votes

    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.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

    History

    Follow 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-08-14 mmuetzel StatusNeed Info Ready For Test
        Planned ReleaseNone 11.1.0 (current default)
    2025-08-12 mmuetzel StatusNone Need Info
    2025-08-10 tutissanalio Attached File- Added bug67403-4.cset, #57516
    2025-08-09 tutissanalio Attached File- Added bug67403-3.cset, #57513
    2025-08-08 tutissanalio Attached File- Added class_subsref2.m, #57508
    2025-08-07 tutissanalio Attached File- Added bug67403-2.cset, #57507
    2025-08-07 tutissanalio Attached File- Added bug67403.cset, #57506
    2025-08-07 tutissanalio Attached File- Added class_subsref.m, #57505

    Back to the top

    Powered by Savane 3.16-598c.
    Corresponding source code