I am trying to trace managed object creation/disposing in a CLI/C++ prog:
::System::Diagnostics::Trace::WriteLine(String::Format(
"Created {0} #{1:X8}",
this->GetType()->Name,
((UInt64)this).ToString()));
Which fails with
error C2440: 'type cast' : cannot convert from 'MyType ^const ' to 'unsigned __int64'
Is there a way to keep track of the unique object IDs this way?
Thanks!
First of all, why this doesn't work. Managed handle types ^ aren't pointers. They aren't just addresses. An instance of a managed type can and will be moved around in memory by GC, so addresses aren't stable; hence why it wouldn't let you do such a cast (as GC can execute at any moment, and you do not know when, any attempt to use such an address as a raw value is inherently a race condition).
Another thing that is often recommended, but doesn't actually work, is Object.GetHashCode(). For one thing, it returns an int, obviously not enough to be unique on x64. Furthermore, the documentation doesn't guarantee that values are unique, and they actually aren't in 2.0+.
The only working solution is to create a an instance of System.Runtime.InteropServices.GCHandle for your object, and then cast it to IntPtr - that is guaranteed to be both unique, and stable.
Check out the GCHandle type: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx. Looks like it would do what you want, though it looks it would be a bit of a pain to use for your purposes...
Even if you could cast this to some integral value for display, it probably wouldn't be a useful unique identifier. This is because unlike C++, in C++/CLI the location of a (managed) object (and by extension the value of this) can potentially change during that object's lifetime. The (logically) same object could print two different strings at different points in the program.
MyType ^const is a reference type. Hence it's in the managed memory space, and you can't get direct memory pointers to these types, as they can change at any time.
Is there a way to keep track of the unique object IDs this way? Thanks!
You could use MyType.GetHashCode();
Related
There seems to be a difference in the implementation of PrimitiveBoxingDelegate and PrimitiveUnboxingDelegate.
Basically I would like to box a primitive value on the stack, so it can be returned as a reference (ie. the method returns Object)
PrimitiveUnboxingDelegate.forPrimitive() provides me with a StackManipulation but unfortunately PrimitiveBoxingDelegate.forPrimitive() does not.
Is there an easy way to create a boxing StackManipulation?
You can, you just need to specify the type to which the value should be boxed to what is implicit for unboxing:
StackManipulation sm = PrimitiveBoxingDelegate
.forPrimitive(...)
.assignBoxedTo(..., Assigner.DEFAULT, Assigner.Typing.STATIC);
You can cast an int to for example a Object or a Number. You can however create illegal combinations as well what is sometimes necessary for Byte Buddy's own purposes.
After some discussion on the question found here Correct execution of Final routine in Fortran
I thought it will be useful to know when a function with a pointer result is appropriate to use with a normal or a pointer assignment. For example, given this simple function
function pointer_result(this)
implicit none
type(test_type),intent(in) pointer :: this
type(test_type), pointer :: pointer_result
allocate(pointer_result)
end function
I would normally do test=>pointer_result(test), where test has been declared with the pointer attribute. While the normal assignment test=pointer_result(test) is legal it means something different.
What does the normal assignment imply compared to the pointer assignment?
When does it make sense to use one or the other assignment?
A normal assignment
test = pointer_result()
means that the value of the current target of test will be overwritten by the value pointed to by the resulting pointer. If test points to some invalid address (is undefined or null) the program will crash or produce undefined results. The anonymous target allocated by the function will have no pointer to it any more and the memory will be leaked.
There is hardly any legitimate use for this, but it is likely to happen when one makes a typo and writes = instead of =>. It is a very easy one to make and several style guides recommend to never use pointer functions.
I'm using reflection to serialize an object. Getting the values as objects is a real murder on performance due to late binding penalties. CType / DirectCast can get rid of most of it but I can't feed a type variable into it so currently I'm using a switch case block on the type variable to select the correct DirectCast.
It came to my attention that CTypeDynamic exists and takes type variables but the return type is Object so... it converts an object into an object, cool. That got me wondering, what is the purpose of this function?
The CTypeDynamic function looks for dynamic information and performs the cast/conversion appropriately. This is different from the CType operator which looks for static information at compile time or relies on the types being IConvertible.
This function examines the object at runtime including looking for Shared (aka static) custom operators. As always, if you know the type then use CType, but if you need dynamic casting then you need to use CTypeDynamic.
More information here: http://blogs.msmvps.com/bill/2010/01/24/ctypedynamic/
Putting aside good programming practises. Ill give context after.
With respect to Objective-C string literals #"foobar"
Does this structure...
NSString *kFoobar = #"foobar";
[thing1 setValue:xyz forKey:kFoobar];
[thing2 setValue:abc forKey:kFoobar];
[thing3 setValue:def forKey:kFoobar];
[thing4 setValue:ghi forKey:kFoobar];
Use more runtime memory than this structure...
[thing1 setValue:xyz forKey:#"foobar"];
[thing2 setValue:abc forKey:#"foobar"];
[thing3 setValue:def forKey:#"foobar"];
[thing4 setValue:ghi forKey:#"foobar"];
Or does the compiler sort things out and merge all instances of #"foobar" into a single reference in the TEXT section
Context...
I have inherited a large amount of source code in which most keys are expressed as string literals rather than string constants. Its not mine and the owner isn't going to pay for nice to have. Is there any point to spending time on constantifying the strings from a runtime view.
I did pass the exe through strings and it appears as if the compiler does the heavy lifting but I'm not sure.
The two are, for all intents and purposes, identical. Only one instance of a given literal string is created per compilation unit. (And, in fact, in some cases even less, since the system will attempt to combine them.)
The var kFoobar used in the first example would, if a local var, be a temporary which may never be more than a register. At most it would occupy 8 bytes in the stack frame that goes away on method exit. And the compiler would likely load a temp to point to the literal anyway, for the second case. So the code for the two examples could actually be identical.
If kFoobar were some sort of instance or global var then the pointer var itself it would of course occupy instance or global space, but it would have no other effect.
And the NSMutableDictionary does not need to make a local copy of the string (when it's used as a key) because NSString is immutable. The single copy is shared by all referencing objects.
Check out this quote from here, towards the bottom of the page. (I believe the quoted comment about consts apply to invariants as well)
Enumerations differ from consts in that they do not consume any space
in the final outputted object/library/executable, whereas consts do.
So apparently value1 will bloat the executable, while value2 is treated as a literal and doesn't appear in the object file.
const int value1 = 0xBAD;
enum int value2 = 42;
Back in C++ I always assumed this was for legacy reasons, and old compilers that couldn't optimize away constants. But if this is still true in D, there must be a deeper reason behind this. Anyone know why?
Just like in C++, an enum in D seems to be a "conserved integer literal" (edit: amazing, D2 even supports floats and strings). Its enumerators have no location. They are just immaterial as values without identity.
Placing enum is new in D2. It first defines a new variable. It is not an lvalue (so you also cannot take its address). An
enum int a = 10; // new in D2
Is like
enum : int { a = 10 }
If i can trust my poor D knowledge. So, a in here is not an lvalue (no location and you can't take its address). A const, however, has an address. If you have a global (not sure whether this is the right D terminology) const variable, the compiler usually can't optimize it away, because it doesn't know what modules can access that variable or could take its address. So it has to allocate storage for it.
I think if you have a local const, the compiler can still optimize it away just as in C++, because the compiler knows by looking at its scope whether or not anyone is interested in its address or whether everyone just takes its value.
Your actual question; why enum/const is the same in D as in C++; seems to be unanswered. Sadly there exists no good reason for this choice whatsoever. I believe that this was just an unintentional side effect in C++ that became a de facto pattern. In D the same pattern was needed, and Walter Bright decided that it should be done as in C++ such that those coming from that place would recognize what to do ... In fact, before this rather IMHO silly decision, the keyword manifest was used instead of enum for this usecase.
I think a good compiler/linker should still remove the constant. It's just that with the enum, it's actually guaranteed in the spec. The difference is primarily a matter of semantics. (Also keep in mind that 2.0 isn't complete yet)
The real purpose of enum being expanded syntactically to support single manifest constants, from what I understand, is that Don Clugston, a D template guru, was doing some crazy stuff with templates. He kept running into long build times, ridiculous compiler memory usage, etc. because the compiler kept creating internal data strucutres for const variables. One key thing about const/immutable variables compared to enums is that const/immutable variables are lvalues and can have their address taken. This means there is some extra overhead for the compiler. This usually doesn't matter, but when you're executing really complicated compile-time metaprograms, even if const variables are optimized away, this is still significant overhead at compile time.
It sounds like the enum value will be used "inline" in expressions where as the const will actually take storage and any expression referencing it will be loading the value from the memory storage.
This sound similar to the difference between const vs. readonly in C#. The former is a compile-time constant and the later is a run-time constant. This definitely affected versioning of assemblies (since assemblies referencing a readonly would receive a copy at compile time and would not get a change to the value if the referenced assembly was rebuilt with a different value).