MATLAB Answers

How to protect against writing to structure passed as input only in generated code?

3 views (last 30 days)
shlomix
shlomix on 22 Aug 2017
Commented: Robert on 23 Aug 2017
I have a function with many structures as inputs and one output. To simplify it let's write it like this:
function sOut = myfun(sOut,sIn1,sIn2)
sOut.a = sIn1.a + sIn2.a;
sOut.b = sIn1.b + sIn2.b;
end
When generating c-code all the inputs are passed by referance, while sIn1 & sIn2 are marked as const and sOut is not const. A problem arises if accidentally somone modifies sIn1.a, for example:
function sOut = myfun(sOut,sIn1,sIn2)
sIn1.a = sIn1.a + 1;
sOut.a = sIn1.a + sIn2.a;
sOut.b = sIn1.b + sIn2.b;
end
In such case in generated code sIn1 is no longer passed as const but as a usual pointer, meaning that sIn1 is modified during call of myfun, although it is not an output!
I expect Matlab Coder at least to make a local copy instead of writing to a variable passed as input only, and really what I want to know is there a way to specifiy that sIn1 & sIn2 are inputs only, generating compilation error or something if they are treated otherwise? Passing the inputs structures by value is not an option.
In reality such accident can happen in a project with many functuions edited by diffrent people, and it is difficult to detect.
  1 Comment
Adam
Adam on 22 Aug 2017
Being able to define constness on functions and inputs is a big miss from Matlab compared to other languages (well, C++ that I am familiar with), especially using OOP, as I do, with handle-derived objects that are passed around by reference within Matlab.
(Not in any way a solution to your problem, hence a comment, not an answer, just a thought on the general subject!)

Sign in to comment.

Answers (1)

Robert
Robert on 22 Aug 2017
To address this issue in your example, I renamed the inputs to *_in and then assigned them to variables under your original names at the top of the function. This amounts to a (deep) copy operation in MATLAB, but in the generated code, that operation is optimized away. The result does not have the side effect on sIn1.
Generating code for
function sOut = myfun(sOut,sIn1,sIn2)
sIn1.a = sIn1.a + 1;
sOut.a = sIn1.a + sIn2.a;
sOut.b = sIn1.b + sIn2.b;
end
gave me
void my fun(struct0_T *sOut, struct0_T *sIn1, const struct0_T *sIn2)
{
sIn1->a++
sOut->a = sIn1->a + sIn2->a;
sOut->b = sIn1->b + sIn2->b;
}
But by changing the function to
function sOut = myfun(sOut,sIn1_in,sIn2_in)
% New
sIn1 = sIn1_in;
sIn2 = sIn2_in;
% Same as before
sIn1.a = sIn1.a + 1;
sOut.a = sIn1.a + sIn2.a;
sOut.b = sIn1.b + sIn2.b;
end
I got the following code
void my fun(struct0_T *sOut, const struct0_T *sIn1_in, const struct0_T *sIn2_in)
{
sOut->a = (sIn1_in->a + 1.0) + sIn2_in->a;
sOut->b = sIn1_in->b + sIn2_in->b;
}
In short: copy the inputs so that side effects change the copies and not the input variables and MATLAB Coder should optimize away the copy operation.
  3 Comments
Robert
Robert on 23 Aug 2017
When you say you had the same thoughts, do you mean you tried this and my suggestions didn't help you? Or it worked but you hope for a nicer solution? If it worked, you could consider marking this answer correct to help future visitors with similar problems. If it didn't, would you consider submitting a bug report about the different behavior in MATLAB versus the generated code?

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!