Tomas said:
Hi Edward,
Is the packing alignment of __nogc classes stored as part of the
assembly ? I think it must as the compiler, when referencing the
assembly, could not know how the original data is packed otherwise.
Yet, in my understanding, attributes are only __gc and __value class
specific and do not apply to __nogc classes. Is this correct ? If
so, how is the packing alignment of __nogc classes stored ?
Well, I don't think the packing is actually stored. When the compiler
creates metadata (very basic metadata indeed) for __nogc classes, it
does so by creating them as opaque value types, which means basically
it creates them as value types containing no members, and only basic
information on layout and size.
Here's an example of one such __nogc class represented:
.class private sequential ansi sealed A
extends [mscorlib]System.ValueType
{
.pack 1
.size 12
} // end of class A
Notice the .pack and .size directives, which tell the runtime how to
pack the type and size of the type.
Is this from the assembly itself ? If so, it looks like the assembly is
storing a .pack directive.
AFAIK, the compiler will *always* mark __nogc types with .pack 1,
even if actual packing is different.
This is strange. Suppose I need a different packing for __nogc classes to
correspond to some already created data structure. How do I tell the
compiler to change the packing. In non-CLR code I would use "#pragma pack".
Is this still accepted in __nogc classes in a CLR assembly ? If it is, why
does the compiler ignore it and always insert a .pack 1 directive ?
However, the compiler *will*
adjust the .size directive so that it reflects the real size of the
object in memory according to it's packing. In this case, I was
trying with a class contaning an int, a char and another int, with
packing set to 4. If I set it to 1, then the code would've said
".size 9", and so on.
Your explanation has confused me. Could you please be clearer as to:
1) whether there is a way to set the packing size for __nogc classes.
2) what that way is.
3) whether or not the end-user changing the packing from the IDE affects the
packing for __nogc classes if no specific packing has been set via 1) or 2).
The reason for this post has to do with a potential common problem pre-.NET
having to do with packing of classes/structures. If the programmer/creator
of a struct/class does not specifically set a packing size, via the #pragma
pack directive, when the compiler saw the header file it would apply
whatever the packing was in the IDE ( or command-line ). This could lead to
ABI problems if a library was built with a particular packing for a
class/structure and the end-user of that library decided to change the
global packing in the IDE ( or command-line ) to some other value. The
solution to this problem was for the programmer/creator to set the packing
for the class.structure in the header file for the class/structure via
"#pragma pack". Then the compiler would honor this directive by overriding
the end-user's global packing for that particular class/struct and all would
be well with no ABI problem occurring. Every 3rd party implementation which
distributed C++ header files/library would of course use the "#pragma pack"
method to assure that no ABI problem would occur.
I wanted to make sure that this would work properly with .NET C++ components
with __nogc classes. I am, of course, assuming that __gc and __value classes
store their packing as part of the metadata. My problem is that I want to be
assured that for __nogc classes that the end-user changing the global
packing will not affect the way the compiler/linker access data and
alignment in __nogc classes. Since __nogc ( and __gc and __value ) classes
in assemblies have no header file, I can only think that the packing used
when the assembly is built is somehow picked up and correctly used no matter
what the global packing in the IDE ( or command-line ) happens to be. If
this is the case, I will not worry about putting "#pragma pack" around my
__nogc classes since I don't need to change the default packing for __nogc
classes.