bugGNU Octave - Bugs: bug #44665, Cannot create object array using...

 
 

bug #44665: Cannot create object array using bracket syntax

Submitter:  -X- <jsh>
Submitted:  Mon 30 Mar 2015 06:40:35 AM UTC
   
 
Category:  Classdef Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Feature Request
Status:  Confirmed Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Thu 06 Nov 2025 07:53:56 PM UTC, comment #16: 

Not exactly sure why there's still a conflict, but I had to do the same fix when I applied Fernando's patch to the default.

Thomas <kolmanthomas>
Thu 06 Nov 2025 07:18:52 PM UTC, comment #15: 

After fixing the conflict (moved the tests to the end of the file), the tests pass locally for me.

Colin Macdonald <cbm>
Thu 06 Nov 2025 06:47:46 PM UTC, comment #14: 

Patch doesn't apply to today's default for me:

patch -p1 --dry-run  < bug44665-4.cset

checking file libinterp/corefcn/data.cc
checking file test/classdef/class_pair.m
checking file test/classdef/class_pair_elem.m
checking file test/classdef/classdef.tst
Hunk #1 FAILED at 261.
1 out of 1 hunk FAILED
checking file test/classdef/module.mk
Hunk #1 succeeded at 15 (offset 2 lines).


Colin Macdonald <cbm>
Thu 06 Nov 2025 03:43:27 PM UTC, comment #13: 

Woops, I did forget to add those files. I've re-added them. I also added my name as co-author to the attached patch.

(file #57787)

Thomas <kolmanthomas>
Thu 06 Nov 2025 08:01:25 AM UTC, comment #12: 

Good, you can add your name as co-author of the patch. I think you forgot to add files class_pair.m and class_pair_elem.m to the changeset.

Fernando <tutissanalio>
Thu 06 Nov 2025 05:21:17 AM UTC, comment #11: 

I made some modifications to your patch. I stripped some whitespace and did the following:

- The modification you proposed in comment #8.


@@ -1756,10 +1756,7 @@
           if (obj.is_array ())
             array_list[j] = obj.array_value ();
           else
-            {
-              array_list[j].clear (dim_vector (1,1));
-              array_list[j](0) = obj;
-            }
+            array_list[j] = Array<cdef_object> (dim_vector (1,1), obj);
         }

       arr = Array<cdef_object>::cat (dim, n_args, array_list);


- I simplified the code to check if the object is a classdef.


@@ -1852,6 +1849,8 @@

   interpreter& interp = __get_interpreter__ ();

+  cdef_manager& cdef_mgr = __get_cdef_manager__ ();
+
   symbol_table& symtab = interp.get_symbol_table ();

   octave_value ov_fcn = symtab.find_method (cattype, dtype);
@@ -1901,23 +1900,11 @@
       tmp.resize (j);

       // See if dominant type is a classdef
-      ov_fcn = symtab.find_function (dtype);
-      bool is_classdef = false;
-      if (ov_fcn.is_function ())
-        {
-          octave_function *fcn = ov_fcn.function_value ();
-          if (fcn && fcn->is_classdef_meta ())
-            {
-              octave_classdef_meta *meta_obj
-                = dynamic_cast<octave_classdef_meta *> (fcn);
-              if (meta_obj->is_classdef_constructor ())
-                is_classdef = true;
-            }
-        }
-
-      if (is_classdef)
+      cdef_class cdef = cdef_mgr.find_class (dtype, false);
+
+      if (cdef.ok ())
           // Default classdef concat
-          retval = do_single_type_concat_cdef(tmp, dim);
+          retval = do_single_type_concat_cdef (tmp, dim);
       else
         {
           // Default struct-based class concat


I'll see what I can do about fixing find_method in symbol_table. So, I don't think we need to add tests just yet covering more implicit class conversion cases.

I recommend that this patch be applied before Octave 11's release.

(file #57780)

Thomas <kolmanthomas>
Wed 05 Nov 2025 09:38:06 PM UTC, comment #10: 

Thanks for reviewing, Thomas.

Fernando <tutissanalio>
Wed 05 Nov 2025 07:04:28 PM UTC, comment #9: 

Thanks for implementing this. The usual case of concatenating objects of a single classdef works flawlessly with your patch.

You are correct that attempt_type_conversion does not find any class conversion methods or constructors; this is because find_method in symtab.cc is broken. I'm going to analyze the current behaviour of your patch with that in mind.

Here are MATLAB's rules for implicit class conversion when concatenating: https://www.mathw ... s-conversion.html. I think it would be helpful to any other developers reading this if I checked the status of your code against the rules written there. For the following examples, I will use this example new-style classdef:


classdef nsc
  properties
    data
  end

  methods
    function obj = nsc(data)
      if nargin == 0
        data = 0;
      end
      obj.data = data;
    end
  end
end

It has a constructor defined that can do type conversion for some (all?) objects. With that in mind,

> In concatenation operations, the dominant object determines the class of the resulting array. MATLAB determines the dominant object according to these rules:
>
>  - User-defined classes are dominant over built-in classes such as double.


This works according to your patch. If I try

>> [ 2 nsc ]
error: no constructor for nsc!

which is basically saying, I'm trying to convert 2 to an object of type nsc. So the logic is good there.

> - If there is no defined dominance relationship between any two classes, then the leftmost object in the concatenation statement is dominant. For more information on class dominance, see Method Invocation.


Works well in your patch in the case where there is no defined dominance relation. If my patch (implementing InferiorClasses support) over at https://savannah. ... .org/patch/?10537 is applied, then it will also work if there is a defined dominance relation. For an example, consider the classdef nsc_dominant which has the same properties and methods as nsc, but is dominant to nsc:


classdef (InferiorClasses = {?nsc}) nsc_dominant

Then

>> [ nsc nsc_dominant ]
error: no constructor for nsc_dominant!

seems to work, as it is trying to convert an object of type nsc to an object of type nsc_dominant. So, your patch works as expected here with my patch attached.

In the link here: https://www.mathw ... rent-classes.html, we have the following statement:

> MATLAB does not convert objects to a common superclass unless those objects are part of a heterogeneous hierarchy. For more information, see Designing Heterogeneous Class Hierarchies.


Your patch doesn't touch on this because Octave doesn't have support for heterogeneous arrays in general. So all good here.

-----

One bug that is semi-related to concatenation:
 
- In Octave, it is possible to name a classdef as a built-in type. For example,


classdef char
end

If you concatenate it with an actual char.


>> [ char 'hello' ]
error: octave_base_value::classdef_object_value(): wrong type argument 'sq_string'


which is just nonsensical, but the root of the issue here is naming the classdef `char`, and Octave not prohibiting that from happening. So once again, the patch works as expected here.
 

Thomas <kolmanthomas>
Fri 29 Aug 2025 10:01:01 AM UTC, comment #8: 

My knowledge of C++ is limited. It's probably better to modify the proposed patch in this way:

diff -r e88cafe70cc8 libinterp/corefcn/data.cc
--- a/libinterp/corefcn/data.cc Tue Aug 26 18:14:13 2025 +0200
+++ b/libinterp/corefcn/data.cc Fri Aug 29 11:50:35 2025 +0200
@@ -1756,10 +1756,7 @@
           if (obj.is_array ())
             array_list[j] = obj.array_value ();
           else
-            {
-              array_list[j].clear (dim_vector (1,1));
-              array_list[j](0) = obj;
-            }
+            array_list[j] = Array<cdef_object> (dim_vector (1,1), obj);
         }

       arr = Array<cdef_object>::cat (dim, n_args, array_list);


Fernando <tutissanalio>
Tue 26 Aug 2025 04:17:23 PM UTC, comment #7: 

A small correction again: use clear instead of resize in do_single_type_concat_cdef.

(file #57578)

Fernando <tutissanalio>
Tue 26 Aug 2025 10:16:49 AM UTC, comment #6: 

The same patch with a small correction in a comment of the test file.

(file #57576)

Fernando <tutissanalio>
Tue 26 Aug 2025 09:50:36 AM UTC, comment #5: 

The attached cset implements concatenation of classdef objects. Object conversion relies on existing function attempt_type_conversion and is not perfect: it does not find the classdef constructor when it tries to use it to do the conversion (see test maked as known bug <44665>).

(file #57575)

Fernando <tutissanalio>
Tue 30 Jan 2024 10:09:46 PM UTC, comment #4: 

This is related to bug #65179 and the creation of arrays of classdef objects.  Making this report dependent on bug #65179.

Rik <rik5>
Group administrator
Sun 07 Jun 2020 10:21:21 AM UTC, comment #3: 

This still isn't supported on current dev:

> a = [foo; foo];
warning: struct: converting a classdef object into a struct overrides the access restrictions defined for properties. All properties are returned, including private and protected ones.
error: invalid conversion of multi-dimensional struct to scalar struct


Markus Mützel <mmuetzel>
Group administrator
Thu 21 Apr 2016 04:02:04 PM UTC, comment #2: 

The error message is now:


warning: struct: converting a classdef object into a struct overrides the access restrictions defined for properties. All properties are returned, including private and protected ones.
warning: struct: converting a classdef object into a struct overrides the access restrictions defined for properties. All properties are returned, including private and protected ones.
error: octave_base_value::parent_class_name_list(): wrong type argument 'object'


A way around is:


a(1) = foo();
a(2) = foo()
a =

<object array foo>


Guillaume <gyom>
Tue 02 Jun 2015 04:43:24 PM UTC, comment #1: 

Retagging release from 4.0.0-rc2 to 4.0.0.

John W. Eaton <jwe>
Group administrator
Mon 30 Mar 2015 06:40:35 AM UTC, original submission:  

Concatenation of classdef objects fail with the error messages:

error: invalid conversion of multi-dimensional struct to scalar struct
error: octave_base_value::parent_class_name_list(): wrong type argument 'object'

It seems at least one part of the problem are the '__parent_classes__' and 'parent_class_names' functions which do not seem to support classdef objects.

To test, create a class, for example:


classdef foo
  properties
    bar = 1;
  end
end


and try to concatenate some instances:


a = foo();
[ a a ]
__parent_classes__(a)


If this isn't supported yet maybe a better error message should be printed instead.

-X- <jsh>

 

Attached Files

Attached Files
file #57787:  bug44665-4.cset added by kolmanthomas (7.2KiB - application/octet-stream)
file #57780:  bug44665-3.cset added by kolmanthomas (6.2KiB - application/octet-stream)
file #57578:  bug44665-2.cset added by tutissanalio (7.5KiB - application/octet-stream)
file #57576:  bug44665.cset added by tutissanalio (7.5KiB - application/octet-stream)
file #57575:  bug44665.cset added by tutissanalio (7.5KiB - application/octet-stream)

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

Attach Files:
   
   
Comment:
   

 

Dependencies

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by cbm (Posted a comment)
  • -email is unavailable- added by kolmanthomas (Posted a comment)
  • -email is unavailable- added by tutissanalio (Updated the item)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by amro_octave
  • -email is unavailable- added by gyom (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by jsh (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.

     

    History

    Follow 15 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-11-06 kolmanthomas Attached File- Added bug44665-4.cset, #57787
    2025-11-06 kolmanthomas Attached File- Added bug44665-3.cset, #57780
    2025-08-26 tutissanalio Attached File- Added bug44665-2.cset, #57578
    2025-08-26 tutissanalio Attached File- Added bug44665.cset, #57576
    2025-08-26 tutissanalio Attached File- Added bug44665.cset, #57575
    2024-01-30 rik5 Summaryerror in concatenation of classdef objects Cannot create object array using bracket syntax
        Dependencies- Depends on bugs #65179
    2024-01-23 mmuetzel CategoryInterpreter Classdef
    2024-01-18 rik5 Dependencies- bugs #56323 is dependent
    2020-06-07 mmuetzel Item GroupNone Feature Request
        StatusNone Confirmed
        Release4.0.0 dev
    2019-05-09 siko1056 Dependencies- bugs #53906 is dependent
    2016-12-09 amro_octave Carbon-Copy- Added amro_octave
    2015-06-02 jwe Release4.0.0-rc2 4.0.0

    Back to the top

    Powered by Savane 3.16-ed84.
    Corresponding source code