View Issue Details

IDProjectCategoryView StatusLast Update
000695310000-006: MappingsSpecpublic2021-08-31 16:33
ReporterDavid Levine Assigned ToRandy Armstrong  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Summary0006953: Part 6 (Mappings) Section 5.2.6: Description of how to map structures is confusing
Description

The spec uses this as an example: (Part 6 section 5.2.6)

=====================
struct Type1 {
Int32 X;
Byte NoOfY;
Type2* Y;
Int32 Z;
};

In the C/C++ example above, the Y field is a pointer to an array with a length stored in NoOfY. When encoding an array the length is part of the array encoding so the NoOfY field is not encoded. That said, encoders and decoders use NoOfY during encoding.

This is confusing.

In C/C++ the field NoOfY is a separate field that is unrelated to anything, which to me implies it ought to be encoded along with all other fields.
It is only because we "know" it contains the length of the array pointed to by Y that it should not be encoded - but there is nothing in the struct that makes that clear. Y could point anywhere, making its relationship to NoOfY less clear.
The table below the example shows Y.Length is 4 bytes (Int32) and not a byte containing the length - this is also confusing and does not explain why it is ok to change the type from Byte to Int32

I think a better example would be
struct Type1 {
Int32 X;
Type2[] Y;
Int32 Z;
};

This shows a C/C++ struct that has an explicit array. Its length is made explicit in the encoding as Y.Length. It also implies that the bytes are contained inline in the struct, and not located in a memory location pointed to by Y.
If the goal is to show this in C using pointers, then this would be less confusing

struct Type1 {
Int32 X;
Type2* Y;
Int32 Z;
};

with a note that explains that the length of Y must be made known to the encoder through some other mechanism.

It could also use this (similar to original)

struct Type1 {
Int32 X;
Int32 LengthofY;
Type2* Y;
Int32 Z;
};

with a note that explains that the two fields "LengthOfY" and "Y" combine the semantics of "[]Y". It a kind of RPC syntax, where the size of a field is contained in the value of a different field - in this case, the encoder "knows" it is the number of elements in Y

TagsNo tags attached.
Commit Version
Fix Due Date

Activities

David Levine

2021-06-01 11:02

developer   ~0014443

The example in 5.2.6 shows how to encode a variable length array, but does not show an example of how to encode a fixed length array. Both are needed because the encodings are different. And the ArrayDimensions member of the StructuredField is not shown anywhere.

David Levine

2021-06-01 11:38

developer   ~0014445

As an alternative to the above, to me it makes more sense to use an example that shows a structure, and then show the structure of what the encoded value in the output stream should contain. e.g.
struct Type1 {
Int32 X;
Type2* Y; // an array
Int32 Z;
};

would be encoded as

struct Type1Encoded {
Int32 X;
Int32 LengthOfY;
Type2[] EncodedY;
Int32 Z;
};

with text that explains that LengthOfY is encoded into the output stream, and that EncodedY is a sequence of Ys encoded inline into the output stream.
This would make clear that LengthOfY is 4 bytes added to the stream, and that EncodedY is now inline in the stream, regardless of where in memory the contents of Y is stored in the computer's memory (locality of reference).

A similar example for a fixed length array is needed.

Jim Luth

2021-06-01 16:01

administrator   ~0014448

Agreed to add an example of a fixed size array.

Randy Armstrong

2021-08-14 03:34

administrator   ~0014743

Added fixed length array field to example in OPC 10000-6 - UA Specification Part 6 - Mappings 1.05.3 RC

Randy Armstrong

2021-08-17 16:28

administrator   ~0014753

Reviewed by WG - add to version table before closing.

Jim Luth

2021-08-31 16:33

administrator   ~0014791

Agreed to changes in 1.05.01 Draft 4.

Issue History

Date Modified Username Field Change
2021-05-18 16:40 David Levine New Issue
2021-06-01 11:02 David Levine Note Added: 0014443
2021-06-01 11:38 David Levine Note Added: 0014445
2021-06-01 16:01 Jim Luth Note Added: 0014448
2021-06-01 16:01 Jim Luth Assigned To => Randy Armstrong
2021-06-01 16:01 Jim Luth Status new => assigned
2021-08-14 03:34 Randy Armstrong Status assigned => resolved
2021-08-14 03:34 Randy Armstrong Resolution open => fixed
2021-08-14 03:34 Randy Armstrong Note Added: 0014743
2021-08-17 16:28 Randy Armstrong Note Added: 0014753
2021-08-31 16:33 Jim Luth Status resolved => closed
2021-08-31 16:33 Jim Luth Note Added: 0014791