nasa / fprime

F´ - A flight software and embedded systems framework
https://fprime.jpl.nasa.gov
Apache License 2.0
10.05k stars 1.3k forks source link

Support passing by const reference #722

Open Joshua-Anderson opened 3 years ago

Joshua-Anderson commented 3 years ago
F´ Version latest
Affected Component autocoder

Feature Description

Right now, there is no option in the autocoder to pass by const reference. This makes it impossible to use const references as arguments to port calls. This can be worked around by using const casts to remove the constness of the reference, but this defeats the point of const correctness throughout F'.

Joshua-Anderson commented 3 years ago

@bocchino Since you're working on F'', I was wondering if you have already been thinking about this. Do you have any plans for supporting const references within F''?

bocchino commented 3 years ago

We could add support for this in the FPP model if necessary. However, my sense is that 'const reference' is a lower-level concept than we want to support in the FPP model.

In the FPP model, the main distinction is between "pass by mutable reference" (i.e., allowing the receiver to update a value held by the sender) and "pass by value" (i.e., not allowing that). In the context of a synchronous port invocation, "pass by const reference" is an optimization that provides pass-by-value semantics and avoids extra copies. I feel that this kind of copy-avoidance can be done in the code generator, by inserting const references automatically where appropriate.

bocchino commented 3 years ago

A related point is that const references don't play well with F Prime serializable values, as they currently work. In F Prime, typically what we pass over a port is a small scalar value or a serializable class instance. A small scalar value is OK to pass by value or by mutable reference; const references are not needed. A serializable class instance can't be passed by const reference, because it's a container containing data and metadata, and to do anything with the data (serialize or deserialize it) the receiver needs to update the metadata.

I think if we wanted to pass serializable values by const reference, we would need to extend the semantics of serializable values at the framework level. We would need something like a "constant deserialization handle" that provides a serializable view over here into data stored over there, and supports only deserialization.

bocchino commented 3 years ago

I think if we wanted to pass serializable values by const reference, we would need to extend the semantics of serializable values at the framework level. We would need something like a "constant deserialization handle" that provides a serializable view over here into data stored over there, and supports only deserialization.

This comment applies to serialized buffers (e.g., Fw::Com), but not to serialized class instances with members (e.g., Fw::Time). You can use a const reference to read the members.

bocchino commented 3 years ago

So it turns out that const references can be used for serial buffers, if you want to copy the whole buffer. Where const references don't work is if you want to pull individual items out of the buffer, because that requires updating the metadata.

@rohandkn Is working on the optimization to implement "pass by value" using const references where appropriate.