I'm running in to some strange errors when dabbling in some socket programming using Xcode 4. I get the error that addrinfo is undeclared, despite me simply copying the code from another project that did work (when using Xcode 3). The project is mainly in Objective-C, but I've tested creating another framework with plain C, and the error still remains.
I have the following frameworks included:
ApplicationServices.framework
Cocoa.framework
AppKit.framework
Foundation.framework
No added linker flags either.
However, other functions such as getaddrinfo (that uses addrinfo itself!) exists. Any ideas?
This issue wasn't IDE-related, it was a language issue. How structs are treated is apparently different in C (and thus Objective-c) and C++ (which the previous projects were=. So I changed the line
addrinfo hints;
To:
struct addrinfo hints;
Have you got the correct imports?
#import <netinet/in.h>
#import <sys/socket.h>
A quick grep shows that struct addrinfo is declared in <netdb.h>. Try explicitly including that. (Your Xcode 3 project may have included that, or some other header that includes it, in its prefix file.)
Related
As of Xcode 10.2, there is a new macro for specifying enums in Objective-C, NS_CLOSED_ENUM. Using this in place of NS_ENUM is required, to allow those enums to be used in Swift, as if they were declared in Swift (meaning without either requiring an #unknown handler in switch statements, or getting a warning). See here for more.
It appears that clang-format has not caught up to this new reality, and won't recognize
typedef NS_CLOSED_ENUM(...
the same as it does
typedef NS_ENUM(...
Is this true?
As of these commits (around July 2019), clang-format apparently does support NS_CLOSED_ENUM.
I understand how #import works vs #include, the whole "Only include it if it isn't already included" thing. I also understand that Apple is pretty fond of #import for their Objective-C code, so over in Xcode it's not going anywhere and everything's fine.
What I don't get is in other environments like Android Studio, it says that #import is deprecated and gives warnings if you use it. Why is that?
It's my understanding that #import is functionally different and, in some cases, arguably better than #include, depending on what you need. If that's the case, why deprecate a potentially useful tool, especially if there isn't any sign of it being replaced with something better?
Is there some horrendous flaw in it that makes it wholly undesirable to use, or is it fine?
Because Objective-C is a superset of the C programming language, the #import statement is a minor refinement upon C’s #include statement. The #include statement is very simple; it copies everything it finds in the included file into your code during compilation. This can sometimes cause significant problems. This can creates a loop, and can confuse the compiler. To deal with this, C programmers have to write guards against this type of event from occurring.
When using #import, you don’t need to worry about this issue or write header guards to avoid it. However, #import is still just a glorified copy-and-paste action, causing slow compilation time among a host of other smaller but still very dangerous issues (such as an included file overriding something you have declared elsewhere in your own code.)
From iOS 7, Apple introduced a new way to import file:
#import UIKit;
It's a new feature called Modules or "semantic import". Modules are an attempt to get around above issue. They are no longer a copy-and-paste into source code, but a serialized representation of the included files that can be imported into your source code only when and where they’re needed. By using modules, code will generally compile faster, and be safer than using either #include or #import.
To get more information about this, you can watch WWDC 2013
the more i study and research, the less i understand now.. very frustrating..
But, still try to figure it out i hope anyone who knows in detail, please help me out :)
What i know is when i use "#import(include) (file1)", it does nothing but putting file1 in current source file so that i can.... use the name of file...(I'm not so sure..)
And,
The Question is then when i inherit file1.h, every definition included in file1.m can be inherited..?
What about the "include" case..? it also include file1.m behind the scene..? or my program just knows declaration in file1.h and can refer to real definition at runtime..?
Sorry if my question is a bit not organised cuz even my brain is not organised as well Y.Y
The Question is then when i inherit file1.h, every definition included
in file1.m can be inherited..?
You don't inherit a file, you #include or #import it. Actually the thing is easier than you think.
In any source code file, you use functions and objects. For example you can use NSString or a custom object MyClass. But the compiler and the linker needs to know WHERE is the definition of those objects and functions, so that it can verify the syntax and link with the appropriate libraries.
Say you use MyClass in some source file.
MyClass myclass = [[MyClass alloc] init];
The compiler doesn't know what MyClass is, so you write this
#include "MyClass.h"
This tells the compiler that it should look into that header file when looking up objects. So what about MyClass.m? Well, at the point where you're object is being compiled the contents of MyClass.m don't matter, because that will be resolved later, by the linker.
In objectiveC you will use "import"
In C you will use "include"
In Xcode you can right in c and ObjectiveC.
Basically what is dose, is take the file that you imported and place is before the file that you imported it from, before the program compiles.
For Example if i use "import myViewController.h", in the class "mainViewController.m"
The class that i imported it to("mainViewController.m"), can use all the properties that are at the "#interface" at the "import myViewController.h" file.
Hope my answer is clear enough..
The implications to the visibility of symbols should be exactly the same.
If you are dealing with somelib.h, and in my module.c you #import somelib;
it should give you the same symbols in that compilation unit as if you did #import <somelib.h>
but you wouldn't have to add the framework in your linking phase.
Compiling my project on new xcode4 using llvm 2.0 compiler I get a strange error coming from standard <sqlite3.h> header. Problem is with the following line:
//<sqlite3.h>
typedef struct sqlite3 sqlite3;
Error message:
In file included from /Projects/trunk/MyProj/Classes/StatsProvider.m:14:
Elaborated type refers to a non-tag type in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/include/sqlite3.h
Using GCC 4.2 project compiles with no problem
How can I fix that error?
My guess: you are compiling sqlite as C++ code, whereas you should compile it as plain C code. class/struct keywords implicitly introduce a typedef in C++, but not so in C.
I interpret the error message as the compiler complaining about using struct sqlite3 when it hasn't seen a struct declaration with that name. Struct names are in a special "tag-space".
My next guess is that the new compiler is stricter than the old one, and has found a bug.
I'm currently having some linker problems when trying to compile an Objective-C program and think that the reason why I can't figure out the issue may be due to ignorance as to the compiler process.
Would it be possible for somebody to give me an overview of the steps taken during compilation?
This is as I currently understand the process:
The compiler copies the contents of any included .h files into the file that it was defined in. The compiler does not keep track of whether a .h file has already been included, so it may be included within a project multiple times.
Any .m files are compiled to C equivalent code (which are in turn compiled to object code).
The linker produces links between the declarations made in the .h files and the appropriate functions within the object code. The appropriate functions are determined by looking for them in a .m file of the same name.
The object files are connected together to form the executable, making sure that the main function is situated at the entry point of the executable. Any declarations are then presumably deleted to save space?
Assuming this is correct (which it may not be), this would presumably mean that you should never #include .m files because you will likely end up with multiple method definitions which will cause the linker problems.
Thanks for any illumination anybody can bring to this :).
Cheers,
Danny
You get the idea more or less correctly. A few corrections:
#include doesn't check whether it's already included or not, but #import does check.
.m is not first converted to C and then to object code. It was done that way 20 years ago, but it's no longer the case. It's just directly compiled down to object code.
The linker doesn't care how the file was named. You can use different file names for .h and .m. You can split implementations of functions declared in a .h file into multiple .m files, for example.
Whether unused implementations are deleted or not depends on the compiler and the compiler options.
In any case, your conclusion is correct: you should never include/import an implementation file to another implementation file. You will run into a double-implementation error.