What is the difference between #import and #include in Objective-C?
Asked Answered
G

10

409

What are the differences between #import and #include in Objective-C and are there times where you should use one over the other? Is one deprecated?

I was reading the following tutorial: http://www.otierney.net/objective-c.html#preamble and its paragraph about #import and #include seems to contradict itself or at least is unclear.

Grundy answered 13/1, 2009 at 16:25 Comment(0)
C
361

The #import directive was added to Objective-C as an improved version of #include. Whether or not it's improved, however, is still a matter of debate. #import ensures that a file is only ever included once so that you never have a problem with recursive includes. However, most decent header files protect themselves against this anyway, so it's not really that much of a benefit.

Basically, it's up to you to decide which you want to use. I tend to #import headers for Objective-C things (like class definitions and such) and #include standard C stuff that I need. For example, one of my source files might look like this:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>
Cimbri answered 13/1, 2009 at 16:29 Comment(13)
Even if header files contain include guards, there is still a performance hit during compilation if you use #include -- the compiler must open up each header file to notice the include guards.Hutto
a header guard is a preprocessor directive that ensures a header is only included once in a source file.Cimbri
I think #import is actually an addition by GCC, not by Objective-C. You can use it in non-ObjC languages as long as you compile with GCC (or Clang)Rumpf
@dave - #import is an Objective-C addition to the preprocessor. GCC just supports it in C and C++ source files as well, although they officially suggest not using it in C or C++ in favor of portable, traditional header guards. All Objective-C preprocessors must include #import, however.Cimbri
A header guard is where you add to the top: #ifndef myheader #define myheader ... followed by header code... #endifScudo
So the official recommendation is to avoid using the newer, simpler, better thing for the sake of maintaining compatibility with older things that could just as easily be updated to support the new keyword? That's nonsense. Somebody needs to bring in some new officials.Stat
@aroth: It's not about newer vs. older. It's about standard vs. nonstandard.Rockery
@Rockery - Perhaps. But a standard that doesn't evolve and that recommends dated, clunky, and obtuse ways of doing things is not very valuable, in my opinion. Especially when the capabilities of tools do evolve, and doubly so when "all Objective-C preprocessors must include #import" and when we're talking about code in the context of an Objective-C project.Stat
On a decent compiler, the include guard won't cost at compile time. The header file needs to be included once if you want to use it. When it's included, the compiler will detect the header guard. and remember it. On the second #include for the same file, the compiler knows about the header guard and doesn't even look at the file.Gotthelf
This is not standard vs. nonstandard; it's language vs. language, and one intent vs another. If you're using Objective-C and you intend to include an Objective-C header, use #import. If you're using C, C++ or are using Objective-C and just want to inline one file in another, use #include.Touchandgo
Another thing to note is that C++ has a different approach where you use #pragma once instead of manual header guards. So C++ still uses #include but also solves the problem #import is intended to solve.Thane
@Gotthelf Right, this is called Multiple-Include Optimisation and avoids a file to be unnecessarily reopened.Forest
This nice thing about #import that nobody here seems to mention, is that it's the only solution that doesn't require extra code. It isn't much code either way, but less code for the same thing is usually best. Also lowers the bar slightly for new devs who might not know about header guards or #pragma once.Dukedom
N
388

There seems to be a lot of confusion regarding the preprocessor.

What the compiler does when it sees a #include that it replaces that line with the contents of the included files, no questions asked.

So if you have a file a.h with this contents:

typedef int my_number;

and a file b.c with this content:

#include "a.h"
#include "a.h"

the file b.c will be translated by the preprocessor before compilation to

typedef int my_number;
typedef int my_number;

which will result in a compiler error, since the type my_number is defined twice. Even though the definition is the same this is not allowed by the C language.

Since a header often is used in more than one place include guards usually are used in C. This looks like this:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

The file b.c still would have the whole contents of the header in it twice after being preprocessed. But the second instance would be ignored since the macro _a_h_included_ would already have been defined.

This works really well, but has two drawbacks. First of all the include guards have to be written, and the macro name has to be different in every header. And secondly the compiler has still to look for the header file and read it as often as it is included.

Objective-C has the #import preprocessor instruction (it also can be used for C and C++ code with some compilers and options). This does almost the same as #include, but it also notes internally which file has already been included. The #import line is only replaced by the contents of the named file for the first time it is encountered. Every time after that it is just ignored.

Novotny answered 17/9, 2010 at 22:38 Comment(4)
This is the better answer than accepted one. @Guill, you should change the accepted answer.Damicke
After changing 4 #includes to #imports on a 7000 line template header file, there is a noticeable performance improvement in compilation and XCode intellisense responsiveness. (I don't think I'm imagining it)Hundredpercenter
Would #import and #include behave exactly the same if the file included a #pragma once?Solanaceous
included included*Solanaceous
C
361

The #import directive was added to Objective-C as an improved version of #include. Whether or not it's improved, however, is still a matter of debate. #import ensures that a file is only ever included once so that you never have a problem with recursive includes. However, most decent header files protect themselves against this anyway, so it's not really that much of a benefit.

Basically, it's up to you to decide which you want to use. I tend to #import headers for Objective-C things (like class definitions and such) and #include standard C stuff that I need. For example, one of my source files might look like this:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>
Cimbri answered 13/1, 2009 at 16:29 Comment(13)
Even if header files contain include guards, there is still a performance hit during compilation if you use #include -- the compiler must open up each header file to notice the include guards.Hutto
a header guard is a preprocessor directive that ensures a header is only included once in a source file.Cimbri
I think #import is actually an addition by GCC, not by Objective-C. You can use it in non-ObjC languages as long as you compile with GCC (or Clang)Rumpf
@dave - #import is an Objective-C addition to the preprocessor. GCC just supports it in C and C++ source files as well, although they officially suggest not using it in C or C++ in favor of portable, traditional header guards. All Objective-C preprocessors must include #import, however.Cimbri
A header guard is where you add to the top: #ifndef myheader #define myheader ... followed by header code... #endifScudo
So the official recommendation is to avoid using the newer, simpler, better thing for the sake of maintaining compatibility with older things that could just as easily be updated to support the new keyword? That's nonsense. Somebody needs to bring in some new officials.Stat
@aroth: It's not about newer vs. older. It's about standard vs. nonstandard.Rockery
@Rockery - Perhaps. But a standard that doesn't evolve and that recommends dated, clunky, and obtuse ways of doing things is not very valuable, in my opinion. Especially when the capabilities of tools do evolve, and doubly so when "all Objective-C preprocessors must include #import" and when we're talking about code in the context of an Objective-C project.Stat
On a decent compiler, the include guard won't cost at compile time. The header file needs to be included once if you want to use it. When it's included, the compiler will detect the header guard. and remember it. On the second #include for the same file, the compiler knows about the header guard and doesn't even look at the file.Gotthelf
This is not standard vs. nonstandard; it's language vs. language, and one intent vs another. If you're using Objective-C and you intend to include an Objective-C header, use #import. If you're using C, C++ or are using Objective-C and just want to inline one file in another, use #include.Touchandgo
Another thing to note is that C++ has a different approach where you use #pragma once instead of manual header guards. So C++ still uses #include but also solves the problem #import is intended to solve.Thane
@Gotthelf Right, this is called Multiple-Include Optimisation and avoids a file to be unnecessarily reopened.Forest
This nice thing about #import that nobody here seems to mention, is that it's the only solution that doesn't require extra code. It isn't much code either way, but less code for the same thing is usually best. Also lowers the bar slightly for new devs who might not know about header guards or #pragma once.Dukedom
B
70

I agree with Jason.

I got caught out doing this:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function

For GNU gcc, it kept complaining that time() function was not defined.

So then I changed #import to #include and all went ok.

Reason:

You #import <sys/time.h>:
    <sys/time.h> includes only a part of <time.h> by using #defines

You #import <time.h>:
    No go. Even though only part of <time.h> was already included, as
    far as #import is concerned, that file is now already completely included.

Bottom line:

C/C++ headers traditionally includes parts of other include files.
So for C/C++ headers, use #include.
For objc/objc++ headers, use #import.

Brenn answered 18/11, 2010 at 20:51 Comment(3)
It seems that clang doesn't has this not-defined problem.Serotonin
This is a really great example of why it's challenging to introduce modern functionality (#import) to existing systems in a non-intrusive way. Should the system libraries be updated to better handle #import ... probably not. If they were, it would be at the expense of many existing projects that knowingly or unknowingly rely on the existing behavior. Should language development stop introducing new, helpful, forward-looking features... no. So, it's never as simple as some of comments on the accepted answer suggest it could be.Grill
This is a clear problem of a terrible written include file. And gcc acknowledged this and had restructured their header files completely new. Header files should never depend on any include order.Obryan
O
26

#include works just like the C #include.

#import keeps track of which headers have already been included and is ignored if a header is imported more than once in a compilation unit. This makes it unnecessary to use header guards.

The bottom line is just use #import in Objective-C and don't worry if your headers wind up importing something more than once.

Orts answered 13/1, 2009 at 16:28 Comment(2)
pretending for a minute that I am not familiar with the C #include (mostly because I am not), what is the main difference between #include and #import? Also, can you tell me what a header guard is?Grundy
@Ryan: Look at Sven's answer.Breannabreanne
G
14

I know this thread is old... but in "modern times".. there is a far superior "include strategy" via clang's @import modules - that is oft-overlooked..

Modules improve access to the API of software libraries by replacing the textual preprocessor inclusion model with a more robust, more efficient semantic model. From the user’s perspective, the code looks only slightly different, because one uses an import declaration rather than a #include preprocessor directive:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

or

@import Foundation;  //  Like #import <Foundation/Foundation.h>
@import ObjectiveC;  //  Like #import <objc/runtime.h>

However, this module import behaves quite differently from the corresponding #include: when the compiler sees the module import above, it loads a binary representation of the module and makes its API available to the application directly. Preprocessor definitions that precede the import declaration have no impact on the API provided... because the module itself was compiled as a separate, standalone module. Additionally, any linker flags required to use the module will automatically be provided when the module is imported. This semantic import model addresses many of the problems of the preprocessor inclusion model.

To enable modules, pass the command-line flag -fmodules aka CLANG_ENABLE_MODULES in Xcode- at compile time. As mentioned above.. this strategy obviates ANY and ALL LDFLAGS. As in, you can REMOVE any "OTHER_LDFLAGS" settings, as well as any "Linking" phases..

enter image description here

I find compile / launch times to "feel" much snappier (or possibly, there's just less of a lag while "linking"?).. and also, provides a great opportunity to purge the now extraneous Project-Prefix.pch file, and corresponding build settings, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, and GCC_PREFIX_HEADER, etc.

Also, while not well-documented… You can create module.maps for your own frameworks and include them in the same convenient fashion. You can take a look at my ObjC-Clang-Modules github repo for some examples of how to implement such miracles.

Gilreath answered 18/4, 2014 at 1:37 Comment(0)
H
5

If you are familiar with C++ and macros, then

#import "Class.h" 

is similar to

{
#pragma once

#include "class.h"
}

which means that your Class will be loaded only once when your app runs.

Hairsplitter answered 18/10, 2012 at 12:56 Comment(2)
Is this a supported use of #pragma once? I always thought the pragma needed to be inside the included file to work.Thane
@Thane You are correct. #pragma once is placed in the included file, not the file that performs the include. -1 for that.Gramarye
C
1

#include it used to get "things" from another file to the one the #include is used in. Ex:

in file: main.cpp

#include "otherfile.h"

// some stuff here using otherfile.h objects,
// functions or classes declared inside

Header guard is used on the top of each header file (*.h) to prevent including the same file more then once (if it happens you will get compile errors).

in file: otherfile.h

#ifndef OTHERFILE
#define OTHERFILE

// declare functions, classes or objects here

#endif

even if you put #include "otherfile.h" n time in your code, this inside it will not be redeclared.

Coco answered 1/12, 2009 at 22:39 Comment(0)
T
1

IF you #include a file two times in .h files than compiler will give error. But if you #import a file more than once compiler will ignore it.

Tymes answered 16/7, 2010 at 9:43 Comment(4)
#include the same file twice does not result in an error.Accessory
To complement @KennyTM's comment, #include-ing the same file twice in the same header does not result in a compile error IF the usual header gards (#ifndef FILE_NAME_H #define FILE_NAME_H #end) are there. This is expected practice. Using #import the header guards aren't needed.Highbrow
@jbat100: #include is simply a copy-and-paste mechanism. There is deliberate use of #include more than once without include guards, e.g. the "X macro".Accessory
Including a file twice may result in errors depending on what you include. I've seen C code that used #include to implement a kind of templates. They did a #define, included a header, #undefd and redid the #define, included the same header a second time. This resulted in the code being parameterized, valid, and included twice, as the value of the define was different. So there are advantages to using #include, but if you're using a modern language like C++ or ObjC, you generally don't need this.Thane
L
0

In may case I had a global variable in one of my .h files that was causing the problem, and I solved it by adding extern in front of it.

Lavone answered 10/8, 2015 at 15:47 Comment(0)
O
-1

#include vs #import preprocessor directives

History:

#include -> #import -> [Precompiled Headers .pch] -> [@import Module(ObjC);] -> [import Module(Swift)]

#import is a next generation of #include which solves double inclusion and recursive includes for current .h file. Just single copy of included .h body in the current file

#import == #include + guard

guard looks like

#ifndef <some_unique_name>
#define <some_unique_name>

<header_body>

#endif

#include guardWiki(macro guard, header guard, file guard) - prevents multi including a header by a preprocessor that can slow down a build time

#include and #import uses a kind of copy/paste mechanism - recursively copy .h file body(everything except #include, #import directives. It means that the result file will not contain #include, #import directives)

You can check result if select .m file Product -> Perform Action -> Preprocess ".m"

#include example

//A.h
@interface A : NSObject
- (int)startA;
@end

//ViewController.h
#include "A.h"

ViewController.m after preprocessing

@interface A : NSObject
- (int)startA;

@end

@interface ViewController : UIViewController
@end

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

}
@end

double inclusion example

//A.h
@interface A : NSObject //Build time error: Duplicate interface definition for class 'A'
@end 

//B.h
#include "A.h"

//C.h
#include "A.h"
//#import "A.h" to solve
#include "B.h"

recursive includes example

//A.h
#include "B.h" //Build time error: #include nested too deeply
//#import "B.h" to fix it

@interface B : NSObject //Build time error: Duplicate interface definition for class 'A'
@end


//B.h 
#include "A.h" //Build time error: #include nested too deeply
//#import "A.h" to fix it

@interface B : NSObject //Build time error: Duplicate interface definition for class 'B'
@end

[#import in .h or .m]

Ouzo answered 6/12, 2019 at 11:11 Comment(1)
The answer is confusing. It does not answer the question clearly - "what's the difference?" The last sentence is bad English and can be improved. The answer has too many useless references which aim is not related to answering the question, but to connect other author's answers which also rising questions - why? The approved answer below is pretty clear while old and this one adds nothing.Virgy

© 2022 - 2024 — McMap. All rights reserved.