6.10.0 General
preprocessing-file:
group-opt
control-line:
# include pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-list-opt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
# undef identifier new-line
# line pp-tokens new-line
# error pp-tokens-opt new-line
# pragma pp-tokens-opt new-line
# new-line
A preprocessing directive begins with a # that is the first token on a logical line, and ends at the newline that terminates that line.
Directives are executed in translation phase 2, before the language proper sees the source. Their result is a token sequence presented to phase 3.
6.10.0.1 The status of preprocessing
Preprocessing is retained for source compatibility with C, and it is not part of the semantic type system. It operates on tokens rather than on declarations, and it has no knowledge of types, scopes, or values as the language understands them.
Ocean Edition I therefore treats traditional preprocessing primarily as a compatibility boundary. Existing headers and existing C remain consumable, and native code is expected to use ordinary language facilities where they express the same idea. See syntax.md section 52 and behavior.md section 8.
Preferred:
static const int max_users = 64;
static inline int max_int(int a, int b)
{
return a > b ? a : b;
}
Not preferred:
#define MAX_USERS 64
#define MAX(a, b) ((a) > (b) ? (a) : (b))
The first form has a type, has a scope, evaluates its operands once, appears in a debugger, and can be used as an integer constant expression under clause 6.6.6. This is a programming-model preference rather than a syntactic requirement, and an implementation shall not reject the second form.
An implementation should provide an optional diagnostic for an object-like macro whose replacement list is a single constant, since a static const object is almost always better.
ISO C99 mapping: 6.10.
6.10.1 Conditional Inclusion
if-group:
# if constant-expression new-line group-opt
# ifdef identifier new-line group-opt
# ifndef identifier new-line group-opt
elif-group:
# elif constant-expression new-line group-opt
else-group:
# else new-line group-opt
endif-line:
# endif new-line
Constraints.
The controlling expression of #if and #elif shall be an integer constant expression, and shall not contain a cast, a sizeof expression, or an enumeration constant.
Macro expansion is performed first, and the defined and __has_include operators are evaluated. After that, every remaining identifier is replaced by 0, except that true is replaced by 1 and false is replaced by 0.
The replacement applies to the identifier as it stands after expansion, whatever produced it. An identifier that a macro expanded into true is replaced by 1 in the same way a written true is, because at this point the directive sees only preprocessing tokens and does not know which were written and which were expanded. Therefore:
#if true
/* processed */
#endif
#define ENABLED true
#if ENABLED
/* processed: ENABLED expands to true, which becomes 1 */
#endif
Difference: in ISO C99, true in a #if is an identifier that has not been defined as a macro, and is therefore replaced by 0, so the group above would be skipped. Making the boolean constants keywords under clause 6.4.1.3 requires this adjustment, and it makes the directive agree with the language.
Semantics.
Operand types. Every integer constant in the controlling expression is treated as having type intmax_t, or uintmax_t where the constant is unsigned or carries an unsigned suffix. There are no other operand types, since casts, sizeof, and enumeration constants are excluded.
Arithmetic. The operators behave exactly as clause 6.5 specifies for operands of those types, and clause 6.6.1 applies unchanged. Overflow therefore wraps at the width of intmax_t or uintmax_t rather than at the width of int, because those are the operand types. Comparison follows clause 6.3.1.7 and compares mathematical values.
Traps. An operation that would trap under clause 6.5, such as division by zero, is a constraint violation in a controlling expression, under clause 6.6.1.
Note. An expression may therefore give one answer in #if and another in ordinary code, because the operand widths differ:
#if 2147483647 + 1 > 0
/* processed: the operands are intmax_t, so no wrapping occurs */
#endif
int32_t x = 2147483647;
if (x + 1 > 0)
{
/* not taken: the operands are int32_t, so the addition wraps */
}
This is not an inconsistency in the arithmetic. The same rules are applied to operands of different types, which is what happens everywhere else in the language. A program that needs the two to agree writes the constant with the width it means.
The defined operator is available in the controlling expression:
#if defined(FEATURE) && FEATURE >= 2
defined X and defined(X) produce 1 if X is currently a defined macro name, and 0 otherwise.
A group whose condition is false is not processed, and its contents shall still be a valid sequence of preprocessing tokens, so that a skipped group cannot contain lexical damage.
The __has_include operator.
An implementation shall provide __has_include, usable only in the controlling expression of #if and #elif:
#if __has_include(<stdatomic.h>)
It produces 1 if the named header would be found by the corresponding #include, and 0 otherwise. This is required because the alternative is a configuration script, and a language that can answer the question should answer it.
ISO C99 mapping: 6.10.1, with __has_include new.
6.10.2 Source File Inclusion
# include < h-char-sequence > new-line
# include " q-char-sequence " new-line
# include pp-tokens new-line
The familiar spelling is retained:
#include <stddef.h>
#include "local.h"
The angle-bracket form searches implementation-defined places. The quoted form searches in a manner associated with the including file first, and falls back to the angle-bracket search. The search rules shall be documented.
The third form macro-expands its tokens and then shall match one of the first two forms.
Implementation freedom.
An implementation may process an inclusion textually, structurally, incrementally, or through a precompiled representation. The observable result is the set of declarations and definitions the inclusion contributes, and that result shall be identical across strategies.
No import syntax.
The edition does not introduce module or import syntax merely because implementation technology has improved. Surface compatibility with C is worth more than a nicer spelling for an operation programmers already know. See syntax.md section 53.
Nesting of inclusions shall be supported to at least the depth given in Annex B clause B.1.
ISO C99 mapping: 6.10.2.
6.10.2.1 Repeated inclusion
A header is normally included by several translation units, and often reached more than once within one translation unit through an indirect path. Repeated inclusion of the same logical interface shall not require behavior beyond what this clause specifies.
Two mechanisms are available, and an implementation shall support both.
6.10.2.2 Include guards
The traditional mechanism is an ordinary conditional:
#ifndef BUFFER_H
#define BUFFER_H
...
#endif
This uses no facility beyond conditional inclusion, works in every C implementation, and is the portable choice for a header shared with ISO C source.
6.10.2.3 What a second inclusion does
A second inclusion of the same text is not automatically harmless, and the distinction turns on whether the header declares or defines.
Repeatable without protection. A declaration may appear more than once when every occurrence is compatible, under clause 6.9.5. A header containing only object declarations, function declarations, and typedef declarations of compatible types survives a second inclusion.
Not repeatable. A definition may appear only once, and a second inclusion produces a second definition, which is a constraint violation. This applies to a structure, union, or enumeration definition under clause 6.7.2.4, to a static inline function definition under clause 6.9.1, and to an object definition under clause 6.9.2.
Because a header worth writing almost always contains at least a structure definition or a static inline function, a header reached by #include shall be protected against repeated inclusion, by #pragma once or by an include guard. See clause 6.9.3.
Difference: ISO C99 permits a static inline definition to be repeated in one translation unit under its inline linkage rules. Ocean Edition I has no inline linkage rules, so a repeated definition is simply a repeated definition. The practical requirement is unchanged, since headers have been written with protection for decades.
A header reached by #import needs no protection, because importing is idempotent under clause 6.10.11 and a second import declares nothing a second time. A header intended to be reached both ways should still carry a guard, which costs nothing under import.
An implementation should diagnose an unprotected header that is reached by #include rather than waiting for the duplicate definition to be reported at the second inclusion, because the second report names the wrong line.
6.10.2.4 #pragma once
An implementation shall support #pragma once.
#pragma once
When this directive is processed in a source file, the implementation shall ignore every subsequent inclusion of that same source file within the current translation unit.
Constraints.
The directive shall appear at file scope in a source file, and takes no further tokens. Tokens following once on the same logical line are a constraint violation.
Semantics.
The effect applies to the whole containing file, regardless of where in the file the directive appears. An implementation should nevertheless expect it near the top, and should diagnose a #pragma once that appears after any declaration, since a reader will assume the whole file is protected.
The effect is per translation unit. It says nothing about other translation units, which include the file normally.
A file protected by #pragma once may also carry an include guard. The two mechanisms compose, and neither weakens the other.
File identity.
Whether two inclusions name the same source file is determined by the implementation, which shall document its rule. The question is genuinely target-dependent, because file systems differ on symbolic links, hard links, case sensitivity, and network paths.
An implementation shall satisfy two requirements whatever rule it chooses:
- two inclusions resolving to the same file through the same path shall be recognized as the same file,
- an implementation that cannot determine whether two paths name the same file shall treat them as different files, so that a failure of identification produces a redundant inclusion rather than a missing declaration.
Failing safe in that direction matters. A missed inclusion removes declarations a program needs, and the resulting diagnostic points somewhere unrelated. A redundant inclusion is caught by clause 6.9.5 or is harmless.
Adopted from widespread existing practice. No published C standard specifies #pragma once, and every serious implementation provides it. Leaving it as a compiler detail means that the most common way to write a header is technically outside the language, that its semantics are inferred from implementation behavior rather than stated, and that its failure modes on unusual file systems are folklore. Specifying it costs nothing and settles all three.
The adoption passes clause 1.4.1. It adds no keyword, since #pragma is the existing mechanism for exactly this. It removes a category, because header protection stops being half language and half convention. It leaves source unchanged, since the spelling is the one already in use. See clause 1.4 and clause 2.4.
ISO C99 mapping: new.
6.10.3 Macro Replacement
# define identifier replacement-list
# define identifier ( identifier-list-opt ) replacement-list
# define identifier ( ... ) replacement-list
# define identifier ( identifier-list , ... ) replacement-list
Constraints.
Two definitions of the same macro name shall be identical, token for token and whitespace-separation for whitespace-separation, unless the first was removed by #undef.
A parameter name shall not appear twice in a parameter list.
There shall be no whitespace between the macro name and the ( of a function-like macro definition.
Object-like macros.
The name is replaced by the replacement list.
Function-like macros.
The name followed by ( introduces an invocation. The arguments are the comma-separated token sequences between the parentheses, with commas inside nested parentheses belonging to the inner group.
The number of arguments shall equal the number of parameters, unless the macro has an ellipsis, in which case there shall be at least as many arguments as named parameters. The variable arguments are available as __VA_ARGS__.
Each argument is fully macro-expanded before substitution, except where it is an operand of # or ##.
Rescanning.
After substitution, the replacement list is rescanned for further macro names. A macro is not replaced during the rescanning of its own replacement, which prevents infinite recursion. Once a name has been marked as not replaceable in this way, it stays that way for the rest of the program.
Diagnostics. An implementation should diagnose a function-like macro whose parameter appears more than once in the replacement list and is therefore evaluated more than once, and should suggest a static inline function.
ISO C99 mapping: 6.10.3.
6.10.3.1 The # operator
In a function-like macro replacement list, # followed by a parameter is replaced by a string literal containing the argument's tokens.
Whitespace between tokens becomes one space. Leading and trailing whitespace is removed. A \ is inserted before each " and \ that appears inside a character constant or string literal in the argument.
Constraint. # shall be followed by a parameter name.
6.10.3.2 The ## operator
## concatenates the preceding token with the following one. Concatenation happens after argument substitution and before rescanning.
Constraints. ## shall not appear at the beginning or at the end of a replacement list. The result of concatenation shall be a valid preprocessing token.
6.10.3.3 Scope of a macro definition
A macro definition is in effect from its #define until a matching #undef, or until the end of the translation unit.
#undef of a name that is not defined has no effect and is not an error.
A program shall not #define or #undef an identifier that is reserved under clause 6.4.2.1, including a keyword, defined, __has_include, or a name defined by a standard header the program has included.
Because bool, true, false, null, and NULL are keywords, a definition or removal of any of them is a constraint violation. This is a deliberate consequence of clause 6.4.1.2 and clause 6.4.1.3: a fundamental type, its two values, and the null constant should not be redefinable by any translation unit that feels like it.
A legacy header that defines NULL is therefore a constraint violation when compiled as Ocean Edition I. This is the situation clause 6.10.9 addresses, and it is the most common reason a system header needs to be consumed under C99 rules.
6.10.4 Line Control
#line 100
#line 100 "generated.c"
The directive sets the value that __LINE__ reports for the next source line, and optionally the value that __FILE__ reports.
A path set by #line is recorded as written and is not subject to the path mapping of Annex K clause K.6.1, because the program supplied it. A generator emitting #line shall therefore emit a path that does not depend on the machine it ran on, or the artifact will not be reproducible.
Constraint. The line number shall be a decimal digit sequence with a value between 1 and 2147483647.
Generated source should use #line so that diagnostics point at the original input.
ISO C99 mapping: 6.10.4.
6.10.5 Error Directive
#error unsupported target
The directive causes the implementation to produce a diagnostic message that includes the given tokens, and to stop translating.
ISO C99 mapping: 6.10.5.
6.10.5.1 Warning directive
#warning this path is deprecated
An implementation shall provide #warning, which produces a diagnostic message that includes the given tokens and continues translating.
ISO C99 mapping: new. The directive is universally implemented and pointlessly nonstandard.
6.10.6 Pragma Directive
#pragma name tokens
A pragma requests implementation-defined behavior. A pragma whose first token is not recognized shall be ignored, and an implementation should diagnose it under an optional warning rather than by default, so that portable source can carry pragmas for several implementations.
Standard pragmas.
An implementation shall recognize these, and shall document any others:
| Pragma | Effect |
|---|---|
#pragma STDC FP_CONTRACT on-off-switch |
controls floating-point contraction; the default is OFF |
#pragma STDC FENV_ACCESS on-off-switch |
states that the program accesses the floating-point environment; the default is OFF |
#pragma STDC CX_LIMITED_RANGE on-off-switch |
applies where complex arithmetic is provided |
#pragma once |
causes the containing file to be included at most once per translation unit; required, see clause 6.10.2.4 |
An on-off-switch is ON, OFF, or DEFAULT.
The _Pragma operator.
_Pragma ( string-literal )
The operator destringizes its argument and processes the result as though it were a #pragma directive. It exists so that a macro can produce a pragma.
ISO C99 mapping: 6.10.6, 6.10.9.
6.10.7 Null Directive
A line containing only # has no effect.
ISO C99 mapping: 6.10.7.
6.10.8 Predefined Macro Names
6.10.8.1 Required macros
An implementation shall predefine the following. None of them may be undefined or redefined by a program.
| Macro | Value |
|---|---|
__FILE__ |
a string literal naming the current source file, recorded under Annex K clause K.6.3 |
__LINE__ |
the current source line number, as a decimal constant |
__DATE__ |
the declared translation timestamp, as "Mmm dd yyyy" in UTC |
__TIME__ |
the declared translation timestamp, as "hh:mm:ss" in UTC |
__STDC__ |
1, indicating a standard-conforming C implementation |
__STDC_VERSION__ |
199901L, the compatibility baseline |
__STDC_HOSTED__ |
1 for a hosted implementation, 0 for a freestanding one |
__OCEAN__ |
1, indicating that Ocean Edition I semantics are in effect |
__OCEAN_EDITION__ |
1, the edition number |
__OCEAN_VERSION__ |
a long constant identifying the revision of this specification the implementation targets |
__OCEAN_NAMESPACE__ |
a string literal naming the namespace governing the current source file, or "" in the global namespace |
__DATE__ and __TIME__.
These expand to the declared translation timestamp, not to a reading of the wall clock. The timestamp is part of the build configuration, is determined by Annex K clause K.5.1, and is the same for every translation unit in a build.
__DATE__ uses the format "Mmm dd yyyy", where Mmm is the English month abbreviation as asctime produces it, and dd has a leading space rather than a leading zero for days below 10. __TIME__ uses "hh:mm:ss". Both render the timestamp in UTC, so that a build in one time zone matches a build in another.
Difference: ISO C99 defines these as the date and time of translation, which cannot satisfy clause 4.10. The construct is kept and its source is redefined, which serves the programs that use it while making the build reproducible. A program that records __DATE__ in a version string still records the build's date; the build now chooses that date rather than discovering it.
__FILE__.
__FILE__ expands to the path of the current source file as recorded under Annex K clause K.6.2, or to the name most recently set by a #line directive.
Its value shall not depend on the working directory unless that directory is a declared part of the build configuration, and an implementation should make it relative to the root of the translation.
__OCEAN__ is the macro a program tests to detect the edition:
#ifdef __OCEAN__
process(&values[0]);
#else
process(values);
#endif
Note. __STDC_VERSION__ reports the compatibility baseline rather than the edition, because existing headers test it to decide which C features to use, and Ocean Edition I supports the C99 feature set those tests are asking about.
6.10.8.2 Conditionally defined macros
| Macro | Defined when |
|---|---|
__STDC_IEC_559__ |
the implementation conforms to Annex F |
__STDC_ISO_10646__ |
wchar_t values are ISO/IEC 10646 code points |
__OCEAN_CHECKED__ |
the checked profile of clause 4.6.4 is in effect |
__OCEAN_STRICT__ |
the strict profile of clause 4.6.3 is in effect |
__OCEAN_COMPLEX__ |
the complex extension of clause 6.2.5.2 is provided |
__OCEAN_TIMESTAMP__ |
the declared translation timestamp was set explicitly rather than defaulted, per Annex K clause K.5.1 |
__OCEAN_THREAD_LOCAL__ |
thread storage duration is provided |
An implementation shall not define a macro beginning with __OCEAN other than those listed here and in its own documentation.
ISO C99 mapping: 6.10.8.
6.10.9 Preprocessing and the Edition Boundary
A translation unit is preprocessed under the edition selected for it. Directives do not change the edition, and there is no directive that switches semantics partway through a file. See clause 4.6.1.
A header written for ISO C and included into an Ocean Edition I translation unit is compiled as Ocean Edition I. Constructs that this edition removes will be diagnosed, which is the intended outcome: the header is telling the program something that is no longer true.
An implementation should provide a documented mechanism to consume a legacy header under C99 rules while compiling the including unit as Ocean Edition I, since system headers are not always under the program author's control. The mechanism shall not change the semantics of the including translation unit, and declarations imported through it shall be checked for compatibility at the boundary under clause 6.9.4.
ISO C99 mapping: new.
6.10.10 The #namespace Directive
# namespace string-literal new-line
The directive places the declarations of a source file into the named namespace.
#namespace "net"
#namespace "net::tcp"
Constraints.
The directive shall appear at file scope, outside any namespace definition, and shall precede every declaration in its source file.
At most one #namespace directive shall appear in a source file.
A source file containing a #namespace directive shall not contain a namespace definition. The two forms express the same thing at different sizes, and combining them in one file would leave a reader to work out whether the definition nests inside the directive's namespace or sits beside it.
The string literal shall contain one or more namespace names separated by ::, and shall contain nothing else. Each name shall satisfy the constraints of clause 6.7.10, including the restriction on consecutive underscores.
The directive shall not appear in a file that is reached by #include, because the including file's namespace and the included file's directive would both claim the same text. It may appear in a file reached by #import, which processes the file on its own terms.
Semantics.
Every declaration in the file containing the directive, from the directive to the end of that file, is a member of the named namespace, exactly as though it were enclosed in the corresponding namespace definition.
#namespace "net"
int open(const char *host);
is equivalent to:
namespace net
{
int open(const char *host);
}
The two forms shall not be combined in one file, under the constraint above. A program that wants both a file-wide namespace and a distinct one in the same translation unit uses the definition form for both.
6.10.10.1 The directive governs one source file
The directive governs the source file that contains it, and no other file.
A declaration introduced into that file by a textual #include belongs to the included file rather than to the including one, and is not captured. Therefore:
#namespace "net"
#include <stdio.h> /* the standard library stays in the global namespace */
int open(const char *host); /* net::open */
Without this rule, a namespaced file could not include an ordinary C header at all, since the header's declarations would silently acquire the namespace and stop matching the library they describe.
An implementation identifies a source file by the same rule it uses for #pragma once, under clause 6.10.2.4.
Note. The directive is spelled as a directive rather than as a declaration because it applies to a whole file, and because a construct that governs text from a point onward is what a directive is for. The block form of clause 6.7.10 is available where a smaller region is wanted.
ISO C99 mapping: new. Added under clause 1.5.
6.10.11 The #import Directive
# import < h-char-sequence > new-line
# import " q-char-sequence " new-line
# import pp-tokens new-line
The directive makes the declarations of a header available to the current translation unit.
#import <stdio.h>
#import "net.h"
6.10.11.1 Header naming and search
The header name syntax, the search rules, and the path resolution are exactly those of #include, under clause 6.10.2. The angle bracket form searches implementation-defined places, the quoted form searches in a manner associated with the including file first, and the third form macro-expands its tokens and shall then match one of the first two.
Nothing about locating a header changes. A header reachable by #include is reachable by #import under the same spelling.
Semantics.
#import contributes the declarations of the header. #include contributes its characters.
The difference is stated by three rules.
6.10.11.2 The macro environment
Rule 1: the header is processed in its own macro environment.
The header is preprocessed as though it were the first file of a translation unit whose macro environment contains only the implementation's predefined macros and the macros supplied by the build configuration.
Macros defined by the importing file are not visible to the header. The importing file therefore cannot change what a header means, and a header need not defend itself against the file that consumes it.
/* config.h */
#ifdef FEATURE
int with_feature(void);
#else
int without_feature(void);
#endif
#define FEATURE 1
#import "config.h" /* declares without_feature: FEATURE is not visible */
#include "config.h" /* declares with_feature: FEATURE is visible */
A header cannot be parameterized by importing it. That is the point of the rule rather than a limitation of it, since a header whose meaning depends on the consumer cannot be processed once and reused. A program that needs a textually parameterized header uses #include, which is unchanged and remains available for exactly this.
An implementation should diagnose a #import of a header whose declarations depend on a macro the importing file has defined, where it can determine that the two directives would produce different results.
A header sees what it imports. The rule isolates a header from its consumer, not from its own dependencies. A header that imports another receives that header's exported macros by Rule 2, in the ordinary way:
/* buffer.h */
#import <stddef.h>
struct Buffer
{
size_t length; /* size_t is available: stddef.h contributed it */
};
The environment in which a header is processed therefore consists of the predefined macros, the macros the build configuration supplies, the macros exported by the headers it has itself imported, and the macros it has defined. It never contains a macro from the file that imported it.
This makes a header's meaning a function of the header and its own dependency graph, which is what makes two translation units importing the same header receive the same declarations.
A header shall import what it uses. Under #include, a header can rely on the includer having included something first, and many existing headers do. An imported header cannot, and shall import every header whose declarations or macros it depends on. This is the ordinary discipline of a self-contained header, and an implementation shall diagnose a failure to observe it, since the resulting error is otherwise reported inside the header rather than at the omission.
6.10.11.3 Exported macros
Rule 2: the macros the header defines become visible.
After the header is processed, the macros it defined and did not undefine are added to the importing file's macro environment.
#import <limits.h>
int cap = INT_MAX; /* INT_MAX is available */
Without this rule an imported header could not describe an interface that C expresses with macros, which is most of the standard library.
Where an imported header defines a macro the importing file has already defined, the definitions shall be identical in the sense of clause 6.10.3, and the difference is a constraint violation otherwise.
6.10.11.4 Idempotency
Rule 3: importing is idempotent.
Importing a header that has already been imported into the current translation unit contributes nothing further, and is not an error.
An imported header therefore needs no include guard and no #pragma once. The repeated-definition problem clause 6.10.2.3 describes for #include does not arise, because the second import declares nothing a second time.
Two imports name the same header when the search of clause 6.10.2 resolves them to the same source file, under the file identity rule of clause 6.10.2.4.
Reuse across translation units. Because the environment is isolated, the result of processing a header depends only on the header, on the implementation, and on the build configuration. An implementation may therefore process a header once and reuse the result for every translation unit that imports it. Where it does, the cached result shall be keyed on the whole of the translation input closure of Annex K clause K.3.1 that applies to the header, and Annex K clause K.8.2 governs the cache.
Namespaces and imported headers.
An imported header carries its own namespace membership. A header containing #namespace "net" contributes members of net, reached by qualification:
/* net.h */
#namespace "net"
int open(const char *host);
#import "net.h"
void f(void)
{
net::open(&host[0]);
}
#import never introduces unqualified names, and never changes the namespace of the importing file. A header with no #namespace directive contributes members of the global namespace, which is what every existing C header does.
Constraints.
A #import directive shall appear at file scope and outside any namespace definition. A namespace is a property of the imported header rather than of the point of import, so importing inside a namespace would suggest a capture that does not occur.
6.10.11.5 Mixing with #include
Importing and including the same header.
A header may be both imported and included in one program, and the declarations shall agree. Where a translation unit does both, the ordinary redeclaration rules of clause 6.9.5 apply to the result, and an incompatibility is diagnosed as it would be for any other pair of declarations.
An implementation shall not assume that a header behaves identically under the two directives, since a header whose content depends on the importing file's macros will differ by Rule 1. An implementation should diagnose a header that is reached both ways in one translation unit.
Cycles.
A cycle of imports is a constraint violation, and the implementation shall diagnose it, naming the files in the cycle.
An import cycle is a real error rather than a condition to be absorbed by a guard, because the two headers cannot both be processed in an environment containing the other.
Which directive to use.
New code should prefer #import. It is idempotent, it cannot be perturbed by the file that consumes it, and it does not require a guard.
#include remains available, unchanged, and is the correct choice for a header shared with ISO C source, for a header intended to be textually parameterized by the includer, and for the deliberate multiple-inclusion idiom in which a file is included several times with different macros in effect.
Translation.
#import is processed in translation phase 2, alongside the other directives. Its result is declarations presented to phase 3.
An implementation may process an import textually, structurally, incrementally, or from a cached representation, and shall produce the same result whichever it chooses. The contents of an imported header are part of the translation input closure under Annex K clause K.3.1.
ISO C99 mapping: new. Added under clause 1.5.