-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify nested records. #3130
Clarify nested records. #3130
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this clarification, there seems to be a substantial risk of alignment problems. Isn't this something we should at least comment as a potential problem?
Mixing Integer and Real already has that problem, and I couldn't see any specific comments related to that in actual ABIs I would even say that having a pointer at that place would be more problematic, since there are both 32-bit and 64-bit architectures and they have different pointer sizes with different alignment. |
Extra space Co-authored-by: Henrik Tidefelt <henrikt@wolfram.com>
But isn't that what the different platform directories below |
Obviously you will link with different binaries for 32-bit and 64-bit (possibly after finding the right version in a fat binary). But the point was that having a pointer wouldn't solve anything - but instead introduce new alignment issues for them (including possible padding). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have enough experience with C ABI compatibility issues to either approve or request any specific changes on this. Hoping that there are others who can provide more insightful comments.
Of course, if there's a phone meeting decision in favor of this, I can provide an approving review reflecting that.
While we're looking at these formulations, maybe we could also make this a complete sentence:
I suppose the first comma can simply be replaced by or, right? |
Another related issue is that the Return Type Mapping table only has a reference to section 12.9.1.3 for records in C. That section doesn't really cover the case of returning records, but at least the reference suggests that records can be returned. If 12.9.1.3 should be interpreted to say that a record is also returned by reference (that is, a pointer), how is memory managed in that case? Regardless whether a record is returned by reference or value, I think the table entry should be replaced by a more direct statement, and then a reference to 12.9.1.3 can be mentioned after the table for details on how the C record type is constructed based on the Modelica type. Just like we use Finally, I suggest that we replace the following sentence in 12.9.1.3 by a one row table with distinction between input and output formal parameters, similar to how other type mappings have been described above:
|
That's two separate issues: The second issue is then how is memory managed in C in that case, and the answer is that it depends. Small structs can be returned in registers, but larger ones are allocated by the caller and returned by reference - but that is done by the C-compiler and we shouldn't have to care about in Modelica. (In C++ there are additional considerations for non-trivial classes for calls.) Note that as far as I can see already 2nd edition K&R supported that (I don't have 1st edition); so it has been supported for decades.
Agreed. |
With some scope creep, it would be a further improvement to specify that the type mapping goes specifically to |
I first thought about "and" or possibly "and/or" before realizing that it should just be: Additionally it should talk about its components, not elements - in case someone declares a class nested in the record. |
The use of "void*" shall be kept to a minimum. I don't see that there is an issue for different structs here: The C standard defines that identical structs are the same, I verified that the C++ standard also has this for "layout-compatible" structs (same contents) and allow treating pointers to them interchangeably. |
At least Clang rejects this test program:
This is what it says:
If I convert the program to C, I get the following warning from Clang:
This is why I thought making use of the dreaded |
It's more complicated - in C++ the structs are layout compatible (not compatible); so the compiler will detect the error, but if you add the casts it is guaranteed to work. In C they are compatible (6.2.7 Compatible type and composite type in N1570) if given in different translation unit - but in the example above they are in the same translation unit. In both C and C++ a cast between A* and B* doesn't change any bits as far as I understand, whereas a cast to void* may imply that. |
Exactly what bits could change if casting a record pointer to or from |
I expect at carefully implemented external function to come with a header file corresponding to the implementation in the linked library. This header should be included in the compilation unit where where the external function is called, which means that the tools own representation of the record will coexist with the library's representation in the same translation unit. The only way that I see this can be handled without triggering compiler warnings is thus with a |
Potentially all of them. Different pointer types may have different internal representation (note that void* and char* should explicitly have same representation in C, but pointers to structs are not included). However, you are supposed to get back the same bits when casting back from 'void*' - but that may change the bits. But I don't see the relevance: I'm just trying to clarify existing behavior - which doesn't have any of these issues; and not get side-tracked and feature-creeped into adding more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I see that the question about the function signature could be discussed separately from the storage of the struct data. I'll open a separate issue about this (#3154).
See modelica#3130 (comment) Note that this should be fairly straightforward to implement.
Closes #3128
As explained this is variant A and consistent with the original design in Modelica 1.1-1.4, and also implemented in OpenModelica and Dymola.