Non-constant expression or empty matrix. This expression must be constant because its value determines the size or class of some expression.

81 views (last 30 days)
How should I correctly pass in variable structure fields to support C/C++ code generation? My problem is simplified by the fact that the field name "str" of the following structure is dynamically changing and the exact value can only be determined at runtime
function out = testStruct()%#codegen
s = struct();
for i = 1:3
str = randGenChar();
s.(str) = i;
end
out = s;
end
function str = randGenChar()
basechar = 'abcdefghijklmnopqrstuvwxyz';
idx = randi(numel(basechar));
str = basechar(1:idx);
end
Then execute command line:
codegen -config:mex testStruct.m -report
Non-constant expression or empty matrix. This expression must be constant
because its value determines the size or class of some expression.
Error in ==> testStruct Line: 6 Column: 8
Code generation failed: To view the report, open('codegen/mex/testStruct/html/report.mldatx')

Accepted Answer

Walter Roberson
Walter Roberson on 18 Apr 2023
You don't. Code generation cannot handle dynamically generated field names (except perhaps some that can be somehow resolved at compile time through analysis.)
In C and C++ the only form of dynamic field name access to a struct is either by reinterpret-cast and indexing to the appropriate offset, or else by union against a type that you can index.
Once compiled, in C and C++ the only record of the correspondance between struct field name and offset relative to the beginning of the struct, is held in the debug tables. It is not even held for linkage purposes across multiple source files: in C and C++ you commonly #include header files that define the struct fields each time, and if two different source code files define the struct differently then you are dealing with Undefined Behaviour, and are lucky if the compiler happens to notice.
In C especially, everything is compile-time type checking; after that all that gets passed around is constants and pointers, and the compiled function just knows "under this circumstance access a double at offset 72 relative to the pointer that was passed in".
  4 Comments
Ryan Livingston
Ryan Livingston on 19 Apr 2023
Coder unfortunately doesn't support the level of flexibility you need as the number, names, etc. of struct fields must be determined when generating code. Given that dictionary doesn't support codegen, your best bet would be to choose a different data structure to represent things in the generated code. Keeping 2 cell arrays could make sense
fields = {'field1', 'field2', 'field3'};
data = {value1, value2, value3};
When reading from that, you'd need to do a search through fields to find the corresponding index. Depending on the size of your problem, you then might consider keeping fields in sorted order and doing a binary search to make lookup more efficient.
cui,xingxing
cui,xingxing on 19 Apr 2023
Thanks for the suggestion, hopefully some future version will enhance this support, less user effort to rewrite the code to suit, like end+1 is slowly starting to be supported.

Sign in to comment.

More Answers (0)

Products


Release

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!