MATLAB Answers

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

2 ビュー (過去 30 日間)
shlomix
shlomix 2017 年 8 月 22 日
コメント済み: Robert 2017 年 8 月 23 日
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 件のコメント

Adam
Adam 2017 年 8 月 22 日
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!)

サインインしてコメントする。

回答 (1 件)

Robert
Robert 2017 年 8 月 22 日
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 件のコメント

Robert
Robert 2017 年 8 月 22 日
Two additional thoughts:
1. A realistically complicated function might prevent the optimization of the copy operation and then you are really stuck copying the entire structure for each function call. If the structures are large enough and/or the function called often enough, this may not be an acceptable solution. And I know it doesn't answer your question in the way you suggested, by protecting against those changes via a compile-time error.
2. The MATLAB function that causes the side effect on sIn1 does not cause that same effect when called in MATLAB (because MATLAB copies the input inside a function if it has an need to alter it). This means the MATLAB function and the generated code have different behaviors, which is something (I believe) the MATLAB Coder team tries very hard to eliminate. Perhaps they would consider this a bug? Maybe someone from the MathWorks could comment on this?
shlomix
shlomix 2017 年 8 月 22 日
Thank you for the answer, albeit partial. I had the same thoughts in this regard.
Robert
Robert 2017 年 8 月 23 日
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?

サインインしてコメントする。

タグ

製品

Community Treasure Hunt

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

Start Hunting!

Translated by