Static, extern and inline in Objective-C - objective-c

What do static, extern and inline (and their combinations) mean in Objetive-C using the LLVM compiler?
Also, I noticed that there are CG_EXTERN and CG_INLINE macros. Should we be using those instead?
(I couldn't find a source with a clear explanation so I thought it might be useful to create one here, or point to it if someone knows one)

What do static, extern and inline (and their combinations) mean in Objetive-C using the LLVM compiler?
The same as in C, unless you compile as ObjC++ -- then they mean the same as found in C++.
So here is an introduction for C, but read the links if you are ready to use these because the details are important:
Extern
Summary: Indicates that an identifier is defined elsewhere.
Details: http://tigcc.ticalc.org/doc/keywords.html#extern
Static
Summary (value): Preserves variable value to survive after its scope ends.
Summary (function): Effectively emits unnamed copies - useful for private functions in C, and can be used to escape multiple definition errors when used with inline functions.
Details: http://tigcc.ticalc.org/doc/keywords.html#static
Inline
Summary: Suggests the body of a function should be moved into the callers.
Details: http://tigcc.ticalc.org/doc/gnuexts.html#SEC93
Note that inline and static are quite a bit more complex in C++ (like pretty much everything in C++).
I also found that there are CG_EXTERN and CG_INLINE macros. Should we be using those instead?
No.
Instead, you should specify your own, with your own meanings, if you need this type of functionality. CG_EXTERN and CG_INLINE have specific meanings (which may change), and are meant to be used in their defined context -- also, you don't want to have to include a whole handful of frameworks (all CoreGraphics/ApplicationServices/CoreFoundation/etc.) when you want to specify something is extern in a way that works in C and C++.

Justin covered most of it, but I found some other nice resources for those who want to dig deeper:
By declaring a function inline you tell the compiler to replace the complete code of that function directly into the place from where it was called. This is a rather advanced feature that requires understanding of lower-level programming.
Inline functions
This SO question has an enormous answer about extern variables - variables defined "somewhere else" - but need to be used also "here".
Static preserves variable life outside of scope. The Variable is visible within the scope it was declared.
What does a static variable mean?

Related

Changing a class variable from outside the class

Finally, when I managed to understand how to fix this, that is, how to change the value of an internal dynamic variable, the code has moved on and now it is declared in this way:
my int $is-win = Rakudo::Internals.IS-WIN;
This is a class variable declared inside class Encoding::Builtin. Makes all the sense in the world, since an OS is not something that changes during the lifetime of a variable. However, I need to test this code from other OS, so I would need to access that class variable and assign it a True value. Can I do that using the meta object protocol?
The concept of "class variable" doesn't exist in Perl 6.
The declaration being considered is of a lexical variable, and its lifetime is bound to the scope (bounded by curly braces) that it is declared within. It doesn't have any relationship with the class that's being declared, so there's no way to reach it through the MOP. (That the block in this question happens to be attached to a class declaration is incidental so far as lexical variables go.) Nor is it declared our, so it's not stored in the package either.
The only way a lexical can be accessed - aside from under a debugger - is if something inside of that lexical scope explicitly made it possible (for example, by acquiring a pseudo-package and storing it somewhere more widely visible, or by allowing EVAL of provided code). Neither is happening in this case, so the variable not possible to access.
Perl 6 is very strict about lexical scoping, and that's a very intentional part of the language design. It supports the user in understanding and refactoring the program, and the compiler in program analysis and optimization. Put another way, Perl 6 is a fairly static language when it comes to lexical things (and will likely come to do much more static analysis in future language versions), and a dynamic language when it comes to object things.

If I statically link a C library, will the unused functions be optimized out?

My feeling is that essentially 100% of the time this is what you would want to happen, but I suspect that there might be some theoretical caveats, for example:
Say I statically link the standard library and I use printf but not sprintf. Further suppose that I know that &sprintf == &printf + SPRINTF_OFFSET. How could the compiler know I'm never accessing sprintf like this? Does the standard prohibit it somehow?
If I statically link a C library, will the unused functions be optimized out?
Yes, provided they are not part of an object that is pulled into the link via some other symbol.
To understand how the linker works, read this or this.
How could the compiler know I'm never accessing sprintf like this?
The C language standard prohibits computing a pointer that doesn't point to a valid object, or just beyond the last element of an array. Your example is ill-formed.

What is formal comp. sci. name of this language property?

As a self-taught programmer, my definitions get fuzzy sometimes.
I'm very used to C and ObjC. In both of those your code must adhere to the language "structure". You can only do certain things in certain places. As an example, this is an error:
// beginning of file
NSLog(#"Hello world!"); // can't do this
#implementation MYClass
...
#end
However, in Ruby, anything you put anywhere is executed as the interpreter goes through it. So what is the difference between Ruby and Objective-C that allows this?
At first I thought it was that one was interpreted and the other compiled. Then I read some SO posts and the wikipedia definitions. Interpreted or compiled is a property of the implementation not the language. So that would mean there could (theoretically) be an interpreted implementation of Objective-C? In that case, the fact that a statement cannot be outside the implementation can't be a property of compiled languages, and vice-versa if there was a compiled implementation of Ruby. Or am I wrong in assuming that different implementations of a language would work the same way?
I'm not sure there's a technical term for it, but in most programming languages the context of the statement is extremely important.
Ruby has a concept of a root or main context where code is allowed. Other scripting languages follow this convention, presumably made popular by languages like Perl which allowed for very concise programming.
This allows things like this to be a complete and valid program:
print "Hello world!\n"
In other languages you need to define an entry point, such as a main routine, that is executed instead. Arbitrary code is not really allowed at the top level, which instead is reserved for things like function, type, constant, structure and class definitions.
A language like Ruby has a lot of control over the order in which the code is executed. C, by comparison, is usually composed of separate source files that are then linked together, where there's no inherent order to the way things are linked. All the modules are simply assembled into the final library or executable. This is why the main entry point is required, it defines which function to run first.
In short, it boils down to syntax, context, and language design considerations.
Ruby hides lots of stuff.
Ruby is OO like C++, Objective C and Java, and has main like C but you don't see this.
puts(42) is method call. It is a method of the main object called main. You can see it by typing puts self.
If you don't specify the receiver (receiver.method()) Ruby will use the implicit one, main.
Check available methods:
puts Object.private_methods.sort
Why you can put everything anywhere?
C/C++ look for main method called main, and when C/C++ find it, it will be executed.
Ruby on other hands doesn't need main or other method/class to run first.
It execute code from the first line until it meet the end of file(or __END__ on the separate line).
class Strongman
puts "I'm the best!"
end
is just syntactic sugar for Class.new method:
Strongman = Class.new do
puts "I'm the best!"
end
The same goes for 'module`.
for calls each and returns some kind of object. So you may think of it as something similar to method.
a = for i in 1..12; 42;end
puts a
# 1..12
In the end, it doesn't matter if it is method call or some kind of structure like C's int main(). Programming language decides what it should run first.

Is there anything in the C++0x standard to support separate compilation of templates?

In current g++, I typically include all my templated functions that take the template parameter as an argument because they have to be compiled for each instance.
template<typename T>
class A {
public:
void f() { ... }
};
So in a different source, I would write:
#include <A.hh>
A<int> a1;
a1.f();
A<double> a2;
a2.f();
Sometimes, when I've been desperate to not inline big methods, I've manually specified which classes will be used in the source file, but it's really obnoxious:
template<typename T>
A::A() { ... }
template<typename T>
void A::f() { ... }
A<int>; // manually trigger code generation for int and double
A<double>;
Obviously different IDEs and compilers have mechanisms to support this. Is there anything standard that has been mandated, and/or does g++ support anything like this?
There's nothing in the proposed C++0x standard. In fact, export template has been removed (few compilers implemented it anyway).
As far as inlining is concerned, it's a total non-issue. The compiler is smart enough not to inline functions which are too big, even if they're marked inline and put into a header file.
If you're looking at increased compile times from header files grown bloated from templates, use precompiled headers. These aren't standard, but almost all current compilers provide such a mechanism.
C++0x does have extern template, which allows you to prevent the instantiation of certain templates in a compilation unit. So if you have a template class SomeClass, you can put this in the header:
extern template SomeClass<int>;
extern template SomeClass<double>;
This will prevent users from instantiating the template. In the .cpp file for the template, you can force instantiation with this syntax:
template SomeClass<int>;
template SomeClass<double>;
I've manually specified which classes will be used in the source file, but it's really obnoxious:
A<int>; // manually trigger code generation for int and double
A<double>;
This is not legal (I assume you meant to declare dummy variables here, and missed their name). We will see below why
Is there anything standard that has been mandated, and/or does g++ support anything like this?
C++03 had something called export, but which turned out to be a misfeature. The EDG implemented that feature, and their experience with it indicated that it's not worth the trouble implementing it. And it doesn't provide a useful feature separate compilation usually gives you: Hiding of the code of templates which you once compiled. export still requires the code of templates, be it in raw form or encoded into a mid-level compiler-specific language. See Why we can't afford export. A short example is given by EDG worker David Vandevoorde here.
For C++0x and for C++0x sans export, we have
A function template, member function of a class template, or static data member of a class template shall be deļ¬ned in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required
As this indicates, the only way you can achieve separate compilation is to explicitly instantiate the template you want to have separately compiled. By defining dummy variables, you merely implicitly instantiate the class template. And you do not instantiate the member functions of the class templates that way - you would need to do dummy calls or take their address. And to all this, you are not guaranteed that an implicitly instantiated function won't be discarded if it's not used in the translation unit it was instantiated by, after optimization, based on the above quote.
So you explicitly instantiate the class template, which will explicitly also instantiate its member functions the following way:
template class A<int>;
template class A<double>;
This feature, called export is present even in the current standard of C++. Unfortunately, most compilers, including gcc, do not support it. See here http://gcc.gnu.org/bugs/

Can the gcc static linker properly inline functions from a static library?

If we compile a number of source codes which makes uses of a static library named lib.a, would the inline functions in lib.a get properly inlined with the rest of binaries?
no, they would not. Inlining is an operation on the parse tree and requires access to the source code for both the host and donor sources of the inlined code.
Static libraries have already been compiled from source to binary at the point you use them, so inlining cannot happen.
However, code that is not inlined is also 'proper' and will function just fine (assuming it got compiled into the static library at all).
Well, since in order to even attempt to call an inline function its declaration must be visible at the call site. If it is then inline then the compiler will either inline it or completely ignore the request.
If you are wondering if functions NOT declared inline that were inlined in the library can then also be inlined when you link to the final product...this would depend on the implementation and, assuming it is already capable of LTO (since it did it to the library), it very well might be able to inline them again. You may be required to cause the implementation to include the definition even when it's been inlined everywhere though...all depends on the implementation.
http://crazyeddiecpp.blogspot.com/2010/12/inline-functions-and-you.html