Let's consider the following simple scenario:
// Library.dll
void Foo()
{
// some code
}
// main.c/cpp
int main()
{
// ...
Foo();
// ...
}
First:
From what i know, the caller and the callee must work with the same calling convention. And
if there is a full hand of calling conventions, how is it that we can just link
main.cpp with the Library.dll
and call Foo?
What guarantees that the caller and callee in this case uses the same calling convention?
Is this part of the problems that the COM architecture is trying to solve?
Second: I know there's a way to specify the type of calling convention
when declaring/defining a function. Is there a way to specify
a calling convention to the caller as well?
Clarifiaction
Maybe the question wasn't clear enough.
The question refers to a scenario in which the library was
compiled by some other developer, by an arbitrary compiler.
I compile my own main.cpp with my arbitrary compiler.
How can i be sure that both our compilers "Speak the same language"
with respect to calling conventions?
Related
Data encapsulation, or as I like to call it, Who owns it and who needs to know about it, makes up a lot of object-oriented programming. The who needs to know is often satisfied by accessor methods, but these get to be pretty expensive if they all result in an objc_msgsend just to read a variable. C++ answers the problem with inline methods - use the "inline" keyword before the definition, or define the method within the class declaration, and the compiler puts the accessor code within the caller's code, saving the overhead associated with an actual function call.
class IntWrapper {
public:
int getInt() { return anInt; }
protected:
int anInt;
};
Similar syntax is rewarded by a complier error in Objective-C. Having searched the language guides in Xcode ("[Object-Oriented] Programming with Objective-C"), I don't see any relevant reference to "inline" of a method. Is there such thing as inline in Objective-C? Is it called something else? If anyone could point me to the documentation that references inline, much appreciated.
Using the simple test code:
#interface ClassA : NSObject
{
int anInt;
}
- (int) anInt;
#end
#implementation ClassA
- (int) anInt { return anInt; }
#end
and looking at the assembly of the code that uses it, it looks like about 25 instructions.
All Objective-C methods are dispatched dynamically. They can be overridden by subclasses. They can even be replaced at runtime ("swizzled") by the Objective-C runtime API.
In some ways, they are similar to virtual methods in C++.
As such they can't be inlined.
By the way, the technique you cite violates the principle you cite ("Who owns it and who needs to know about it?"). Putting the implementation in the class declaration exposes implementation detail to clients who don't need to know it. Furthermore, the compiler inlining the code into clients prevents that implementation from changing without a recompile, which is the fragile base class problem. Modern Objective-C avoids the fragile base class problem, which means a framework class can change what instance variables it has without breaking clients.
I will preface this question by stating that what I am about to ask is for educational and possibly debug purposes only.
How are block objects created internally in the Objective C runtime?
I see the hierarchy of classes that all represent various block types, and the highest superclass in the hierarchy, below NSObject, is NSBlock. Dumping for class data shows that it implements the + alloc, + allocWithZone:, + copy and + copyWithZone: methods. None of the other block subclasses implement these class methods, which leads me to believe, perhaps mistakenly, that NSBlock is responsible for block handling.
But these methods seem not to be called at any point during a block's life time. I exchanged implementations with my own and put a breakpoint in each, but they never get called. Doing similar exercise with NSObject's implementations gives me exactly what I want.
So I assume blocks are implemented in a different manner? Anyone can shed a light on how this implementation works? Even if I cannot hook into the allocation and copying of blocks, I would like to understand the internal implementation.
tl;dr
The compiler directly translates block literals into structs and functions. That's why you don't see an alloc call.
discussion
While blocks are full-fledged Objective-C objects, this fact is seldom exposed in their use, making them quite funny beasts.
One first quirk is that blocks are generally created on the stack (unless they are global blocks, i.e. blocks with no reference to the surrounding context) and then moved on the heap only if needed. To this day, they are the only Objective-C objects that can be allocated on the stack.
Probably due to this weirdness in their allocation, the language designers decided to allow block creation exclusively through block literals (i.e. using the ^ operator).
In this way the compiler is in complete control of block allocation.
As explained in the clang specification, the compiler will automatically generate two structs and at least one function for each block literal it encounters:
a block literal struct
a block descriptor struct
a block invoke function
For instance for the literal
^ { printf("hello world\n"); }
on a 32-bit system the compiler will produce the following
struct __block_literal_1 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_1 *);
struct __block_descriptor_1 *descriptor;
};
void __block_invoke_1(struct __block_literal_1 *_block) {
printf("hello world\n");
}
static struct __block_descriptor_1 {
unsigned long int reserved;
unsigned long int Block_size;
} __block_descriptor_1 = { 0, sizeof(struct __block_literal_1), __block_invoke_1 };
(by the way, that block qualifies as global block, so it will be created at a fixed location in memory)
So blocks are Objective-C objects, but in a low-level fashion: they are just structs with an isa pointer. Although from a formal point of view they are instances of a concrete subclass of NSBlock, the Objective-C API is never used for allocation, so that's why you don't see an alloc call: literals are directly translated into structs by the compiler.
As described in other answers, block objects are created directly in global storage (by the compiler) or on the stack (by the compiled code). They aren't initially created on the heap.
Block objects are similar to bridged CoreFoundation objects: the Objective-C interface is a cover for an underlying C interface. A block object's -copyWithZone: method calls the _Block_copy() function, but some code calls _Block_copy() directly. That means a breakpoint on -copyWithZone: won't catch all of the copies.
(Yes, you can use block objects in plain C code. There's a qsort_b() function and an atexit_b() function and, uh, that might be it.)
Blocks are basically compiler magic. Unlike normal objects, they are actually allocated directly on the stack — they only get placed on the heap when you copy them.
You can read Clang's block implementation specification to get a good idea what goes on behind the scenes. To my understanding, the short version is that a struct type (representing the block and its captured state) and a function (to invoke the block) are defined, and any reference to the block is replaced with a value of the struct type that has its invoke pointer set to the function that was generated and its fields filled in with the appropriate state.
Background as I understand it: Objective-C method invocations are basically a C function call with two hidden parameters (the receiver and the selector). The Objective-C runtime contains a function named objc_msgSend() that allows to invoke methods that way. Unfortunately, when a function returns a struct some special treatment may be needed. There are arcane (some might say insane) rules that govern whether the structure is returned like other values or whether it's actually returned by reference in a hidden first argument. For Objective-C there's another function called objc_msgSend_stret() that must be used in these cases.
The question: Given a method, can NSMethodSignature or something else tell me whether I have to use objc_msgSend() or objc_msgSend_stret()? So far we have found out that NSMethodSignature knows this, it prints it in its debug output, but there doesn't seem to be a public API.
In case you want to respond with "why on earth would you want to do that?!", please read the following before you do: https://github.com/erikdoe/ocmock/pull/41
Objective-C uses the same underlying ABI for C on a given architecture, because methods are just C functions with implicit self and _cmd arguments.
In other words, if you have a method:
- (SomeStructType)myMeth:(SomeArgType)arg;
then really this is a plain C function:
SomeStructType myMeth(id self, SEL _cmd, SomeArgType arg);
I'm pretty sure you already know that, but I'm merely mentioning it for other readers.
In other words, you want to ask libffi or any kind of similar library how SomeStructType would be returned for that architecture.
NSMethodSignature has a -methodReturnType that you can inspect to see if the return type is a struct. Is this what you're trying to do?
From http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html:
The rules for which struct types return in registers are always
arcane, sometimes insane. ppc32 is trivial: structs never return in
registers. i386 is straightforward: structs with sizeof exactly equal
to 1, 2, 4, or 8 return in registers. x86_64 is more complicated,
including rules for returning floating-point struct fields in FPU
registers, and ppc64's rules and exceptions will make your head spin.
The gory details are documented in the Mac OS X ABI Guide, though as
usual if the documentation and the compiler disagree then the
documentation is wrong.
If you're calling objc_msgSend directly and need to know whether to
use objc_msgSend_stret for a particular struct type, I recommend the
empirical approach: write a line of code that calls your method,
compile it on each architecture you care about, and look at the
assembly code to see which dispatch function the compiler uses.
I've started using Xcode's refactoring abilities (edit > refactor > extract) and noticed that Xcode offers to extract a method or a function.
I've read here and elsewhere about the differences between the two and understand that a method is connected to a class while a function is not. So I'm not looking for definitions, please.
Assuming that no arguments are involved, when is it appropriate to use one instead of the other? I understand that if something isn't really about the class then it could be a function but again, that's just about the definitions. I'm looking for good ol' use cases.
In my personal case, I'm trying to refactor some code out of the AppDelegate's applicationDidEnterBackground. As it is the only place to handle events upon entering the background, the only way to clean up the code is to extract subroutines into .. well, functions. But they'd be inside AppDelegate.m so wouldn't they be methods?
Hmmm..
Personally, I only use functions if, and only if, the following two requirements are met:
I use it so frequently within a given class, or throughout the project, that it warrants being generalized.
It has no side-effects or context dependancies (none of that void *context mess).
In my opinion, C-style functions should only be used as a last resort or in cases where you truly need functional behavior within this kind of an application. Event handling is both application-specific, and context sensitive, so it's best if you left that alone and focused on refactoring common patterns out.
You use functions when you have a, well, function ;-) You know the definitions: a method has an implicit argument self and can access instance variables using that; a function has no implicit arguments - everything it needs must be passed in.
If you are refactoring part of a larger method, that part does not access instance variables, and you are not refactoring it so that a subclass can override it, then let Xcode build you a function. When its done add static to it so it is private to the class.
In doing this you've lost nothing and made it clear that the piece of code is a function - it does not alter the state of the object.
There is of course no hard line between picking a function and a method, its a fuzzy boundary. If a piece of code, say, just accesses one or two instance variables but does not update them then you might pick a function - again making it clear that the object state is not being modified. But you don't want to pass lots of instance variables in as parameters, that is just hard to read (and inefficient).
Using functions can be good, and its certainly not bad to do so in Objective-C.
Method of a class usually need to access instance variables connected to that class. Functions in Objective-C are not connected to a class, and therefore have no access to any non-public member variables of classes.
Consider the class KNode, which contains member variable _memberVar.
#interface KNode : NSObject {
int _memberVar;
}
#end
Any method of this class could access and change the member variable, but any old function cannot, as it is private.
#implementation KNode
- (void)modify {
_memberVar = 10;
}
#end
The following function will not work
void modify(KNode * node) {
_memberVar = 10;
}
Two small but meaningful advantages of functions:
They can be internal-only by marking them static, or
__attribute__((visibility("hidden"))), which is helpful for framework developers
They can be inlined. For example, I use this pattern for fast lazy queue creation:
static inline dispatch_queue_t sharedQueue() {
static dispatch_queue_t queue;
static dispatch_once_t once;
dispatch_once(&once, ^{
queue = dispatch_queue_create("foo", 0);
});
return queue;
}
I have an ObjectiveC++ project. In the ObjectiveC context I am using ARC and iPhoneSDK 6. In C++ I am using a C++11 compiler.
Lambda functions in C++11 are capturing variables with references. This concept is not really supported by ObjectiveC and by "try and error" I came up with the following solution. Are there any pitfalls I am not aware of?
Is there a better solution to this problem?
typedef std::function<void ()> MyLambdaType;
...
// m_myView will not go away. ARC managed.
UIView * __strong m_myView;
...
// In Objective C context I create a lambda function that calls my Objective C object
UIView &myViewReference = *m_myView;
MyLambdaType myLambda = [&myViewReference]() {
UIView *myViewBlockScope = &myViewReference;
// Do something with `myViewBlockScope`
}
..
// In C++11 context I call this lambda function
myLambda();
The straightforward thing to do would be to let the lambda capture the object pointer variable m_myView (I am assuming from your snippet that this is a local variable), and use it normally inside the lambda:
MyLambdaType myLambda = [m_myView]() {
// Do something with `m_myView`
}
The only concern would be the memory management of m_myView. To be generally correct, the lambda needs to retain m_myView when it is created, and release it when it is destroyed (just like blocks do; because the lambda could be used in a scope where m_myView does not exist).
Reading through the ARC docs, I don't see this situation mentioned specifically, but I believe that it should handle it properly, because (1) captured variables of a C++11 lambda are stored as fields of an anonymous class, which are initialized to the captured value when the lambda is constructed, and (2) ARC properly handles the retaining and releasing of Objective-C object fields of C++ classes on construction and destruction. Unless it says something specifically about lambdas to the contrary, or there's a compiler bug, I see no reason why it should not work.