diff options
Diffstat (limited to 'www/compatibility.html')
-rw-r--r-- | www/compatibility.html | 350 |
1 files changed, 246 insertions, 104 deletions
diff --git a/www/compatibility.html b/www/compatibility.html index cf0d96e2f4ffb..aa6a39dda1b42 100644 --- a/www/compatibility.html +++ b/www/compatibility.html @@ -32,20 +32,24 @@ <li><a href="#c">C compatibility</a> <ul> <li><a href="#inline">C99 inline functions</a></li> + <li><a href="#vector_builtins">"missing" vector __builtin functions</a></li> <li><a href="#lvalue-cast">Lvalue casts</a></li> <li><a href="#blocks-in-protected-scope">Jumps to within <tt>__block</tt> variable scope</a></li> + <li><a href="#block-variable-initialization">Non-initialization of <tt>__block</tt> variables</a></li> + <li><a href="#inline-asm">Inline assembly</a></li> </ul> </li> <li><a href="#objective-c">Objective-C compatibility</a> <ul> <li><a href="#super-cast">Cast of super</a></li> <li><a href="#sizeof-interface">Size of interfaces</a></li> + <li><a href="#objc_objs-cast">Internal Objective-C types</a></li> + <li><a href="#c_variables-class">C variables in @class or @protocol</a></li> </ul> </li> <li><a href="#c++">C++ compatibility</a> <ul> <li><a href="#vla">Variable-length arrays</a></li> - <li><a href="#init_static_const">Initialization of non-integral static const data members within a class definition</a></li> <li><a href="#dep_lookup">Unqualified lookup in templates</a></li> <li><a href="#dep_lookup_bases">Unqualified lookup into dependent bases of class templates</a></li> <li><a href="#undep_incomplete">Incomplete types in templates</a></li> @@ -53,6 +57,7 @@ <li><a href="#default_init_const">Default initialization of const variable of a class type requires user-defined default constructor</a></li> + <li><a href="#param_name_lookup">Parameter name lookup</a></li> </ul> </li> <li><a href="#objective-c++">Objective-C++ compatibility</a> @@ -60,7 +65,7 @@ <li><a href="#implicit-downcasts">Implicit downcasts</a></li> </ul> <ul> - <li><a href="#Use of class as method name">Use of class as method name</a></li> + <li><a href="#class-as-property-name">Using <code>class</code> as a property name</a></li> </ul> </li> </ul> @@ -73,8 +78,9 @@ <h3 id="inline">C99 inline functions</h3> <!-- ======================================================================= --> <p>By default, Clang builds C code according to the C99 standard, -which provides different inlining semantics than GCC's default -behavior. For example, when compiling the following code with no optimization:</p> +which provides different semantics for the <code>inline</code> keyword +than GCC's default behavior. For example, consider the following +code:</p> <pre> inline int add(int i, int j) { return i + j; } @@ -84,11 +90,13 @@ int main() { } </pre> -<p>In C99, this is an incomplete (incorrect) program because there is -no external definition of the <code>add</code> function: the inline -definition is only used for optimization, if the compiler decides to -perform inlining. Therefore, we will get a (correct) link-time error -with Clang, e.g.:</p> +<p>In C99, <code>inline</code> means that a function's definition is +provided only for inlining, and that there is another definition +(without <code>inline</code>) somewhere else in the program. That +means that this program is incomplete, because if <code>add</code> +isn't inlined (for example, when compiling without optimization), then +<code>main</code> will have an unresolved reference to that other +definition. Therefore we'll get a (correct) link-time error like this:</p> <pre> Undefined symbols: @@ -96,17 +104,31 @@ Undefined symbols: _main in cc-y1jXIr.o </pre> +<p>By contrast, GCC's default behavior follows the GNU89 dialect, +which is the C89 standard plus a lot of extensions. C89 doesn't have +an <code>inline</code> keyword, but GCC recognizes it as an extension +and just treats it as a hint to the optimizer.</p> + <p>There are several ways to fix this problem:</p> <ul> <li>Change <code>add</code> to a <code>static inline</code> - function. Static inline functions are always resolved within the - translation unit, so you won't have to add an external, non-inline - definition of the function elsewhere in your program.</li> - - <li>Provide an external (non-inline) definition of <code>add</code> - somewhere in your program.</li> - + function. This is usually the right solution if only one + translation unit needs to use the function. <code>static + inline</code> functions are always resolved within the translation + unit, so you won't have to add a non-<code>inline</code> definition + of the function elsewhere in your program.</li> + + <li>Remove the <code>inline</code> keyword from this definition of + <code>add</code>. The <code>inline</code> keyword is not required + for a function to be inlined, nor does it guarantee that it will be. + Some compilers ignore it completely. Clang treats it as a mild + suggestion from the programmer.</li> + + <li>Provide an external (non-<code>inline</code>) definition + of <code>add</code> somewhere else in your program. The two + definitions must be equivalent!</li> + <li>Compile with the GNU89 dialect by adding <code>-std=gnu89</code> to the set of Clang options. This option is only recommended if the program source cannot be changed or if the @@ -114,6 +136,44 @@ Undefined symbols: be changed.</li> </ul> +<p>All of this only applies to C code; the meaning of <code>inline</code> +in C++ is very different from its meaning in either GNU89 or C99.</p> + +<!-- ======================================================================= --> +<h3 id="vector_builtins">"missing" vector __builtin functions</h3> +<!-- ======================================================================= --> + +<p>The Intel and AMD manuals document a number "<tt><*mmintrin.h></tt>" +header files, which define a standardized API for accessing vector operations +on X86 CPUs. These functions have names like <tt>_mm_xor_ps</tt> and +<tt>_mm256_addsub_pd</tt>. Compilers have leeway to implement these functions +however they want. Since Clang supports an excellent set of <a +href="../docs/LanguageExtensions.html#vectors">native vector operations</a>, +the Clang headers implement these interfaces in terms of the native vector +operations. +</p> + +<p>In contrast, GCC implements these functions mostly as a 1-to-1 mapping to +builtin function calls, like <tt>__builtin_ia32_paddw128</tt>. These builtin +functions are an internal implementation detail of GCC, and are not portable to +the Intel compiler, the Microsoft compiler, or Clang. If you get build errors +mentioning these, the fix is simple: switch to the *mmintrin.h functions.</p> + +<p>The same issue occurs for NEON and Altivec for the ARM and PowerPC +architectures respectively. For these, make sure to use the <arm_neon.h> +and <altivec.h> headers.</p> + +<p>For x86 architectures this <a href="builtins.py">script</a> should help with +the manual migration process. It will rewrite your source files in place to +use the APIs instead of builtin function calls. Just call it like this:</p> + +<pre> + builtins.py *.c *.h +</pre> + +<p>and it will rewrite all of the .c and .h files in the current directory to +use the API calls instead of calls like <tt>__builtin_ia32_paddw128</tt>.</p> + <!-- ======================================================================= --> <h3 id="lvalue-cast">Lvalue casts</h3> <!-- ======================================================================= --> @@ -139,50 +199,117 @@ example, one could use:</p> <h3 id="blocks-in-protected-scope">Jumps to within <tt>__block</tt> variable scope</h3> <!-- ======================================================================= --> -<p>Clang disallows jumps into the scope of a <tt>__block</tt> variable, similar -to the manner in which both GCC and Clang disallow jumps into the scope of -variables which have user defined constructors (in C++).</p> - -<p>Variables marked with <tt>__block</tt> require special runtime initialization -before they can be used. A jump into the scope of a <tt>__block</tt> variable -would bypass this initialization and therefore the variable cannot safely be -used.</p> - -<p>For example, consider the following code fragment:</p> +<p>Clang disallows jumps into the scope of a <tt>__block</tt> +variable. Variables marked with <tt>__block</tt> require special +runtime initialization. A jump into the scope of a <tt>__block</tt> +variable bypasses this initialization, leaving the variable's metadata +in an invalid state. Consider the following code fragment:</p> <pre> -int f0(int c) { - if (c) - goto error; +int fetch_object_state(struct MyObject *c) { + if (!c->active) goto error; - __block int x; - x = 1; - return x; + __block int result; + run_specially_somehow(^{ result = c->state; }); + return result; error: - x = 0; - return x; + fprintf(stderr, "error while fetching object state"); + return -1; } </pre> -<p>GCC accepts this code, but it will crash at runtime along the error path, -because the runtime setup for the storage backing the <tt>x</tt> variable will -not have been initialized. Clang rejects this code with a hard error:</p> +<p>GCC accepts this code, but it produces code that will usually crash +when <code>result</code> goes out of scope if the jump is taken. (It's +possible for this bug to go undetected because it often won't crash if +the stack is fresh, i.e. still zeroed.) Therefore, Clang rejects this +code with a hard error:</p> <pre> t.c:3:5: error: goto into protected scope goto error; ^ t.c:5:15: note: jump bypasses setup of __block variable - __block int x; + __block int result; ^ </pre> -<p>Some instances of this construct may be safe if the variable is never used -after the jump target, however the protected scope checker does not check the -uses of the variable, only the scopes in which it is visible. You should rewrite -your code to put the <tt>__block</tt> variables in a scope which is only visible -where they are used.</p> +<p>The fix is to rewrite the code to not require jumping into a +<tt>__block</tt> variable's scope, e.g. by limiting that scope:</p> + +<pre> + { + __block int result; + run_specially_somehow(^{ result = c->state; }); + return result; + } +</pre> + +<!-- ======================================================================= --> +<h3 id="block-variable-initialization">Non-initialization of <tt>__block</tt> +variables</h3> +<!-- ======================================================================= --> + +<p>In the following example code, the <tt>x</tt> variable is used before it is +defined:</p> +<pre> +int f0() { + __block int x; + return ^(){ return x; }(); +} +</pre> + +<p>By an accident of implementation, GCC and llvm-gcc unintentionally always +zero initialized <tt>__block</tt> variables. However, any program which depends +on this behavior is relying on unspecified compiler behavior. Programs must +explicitly initialize all local block variables before they are used, as with +other local variables.</p> + +<p>Clang does not zero initialize local block variables, and programs which rely +on such behavior will most likely break when built with Clang.</p> + + +<!-- ======================================================================= --> +<h3 id="inline-asm">Inline assembly</h3> +<!-- ======================================================================= --> + +<p>In general, Clang is highly compatible with the GCC inline assembly +extensions, allowing the same set of constraints, modifiers and operands as GCC +inline assembly.</p> + +<p>On targets that use the integrated assembler (such as most X86 targets), +inline assembly is run through the integrated assembler instead of your system +assembler (which is most commonly "gas", the GNU assembler). The LLVM +integrated assembler is extremely compatible with GAS, but there are a couple of +minor places where it is more picky, particularly due to outright GAS bugs.</p> + +<p>One specific example is that the assembler rejects ambiguous X86 instructions +that don't have suffixes. For example:</p> + +<pre> + asm("add %al, (%rax)"); + asm("addw $4, (%rax)"); + asm("add $4, (%rax)"); +</pre> + +<p>Both clang and GAS accept the first instruction: because the first +instruction uses the 8-bit <tt>%al</tt> register as an operand, it is clear that +it is an 8-bit add. The second instruction is accepted by both because the "w" +suffix indicates that it is a 16-bit add. The last instruction is accepted by +GAS even though there is nothing that specifies the size of the instruction (and +the assembler randomly picks a 32-bit add). Because it is ambiguous, Clang +rejects the instruction with this error message: +</p> + +<pre> +<inline asm>:3:1: error: ambiguous instructions require an explicit suffix (could be 'addb', 'addw', 'addl', or 'addq') +add $4, (%rax) +^ +1 error generated. +</pre> + +<p>To fix this compatibility issue, add an explicit suffix to the instruction: +this makes your code more clear and is compatible with both GCC and Clang.</p> <!-- ======================================================================= --> <h2 id="objective-c">Objective-C compatibility</h3> @@ -235,6 +362,47 @@ this problem, use the Objective-C runtime API function </pre> <!-- ======================================================================= --> +<h3 id="objc_objs-cast">Internal Objective-C types</h3> +<!-- ======================================================================= --> + +<p>GCC allows using pointers to internal Objective-C objects, <tt>struct objc_object*</tt>, +<tt>struct objc_selector*</tt>, and <tt>struct objc_class*</tt> in place of the types +<tt>id</tt>, <tt>SEL</tt>, and <tt>Class</tt> respectively. Clang treats the +internal Objective-C structures as implementation detail and won't do implicit conversions: + +<pre> +t.mm:11:2: error: no matching function for call to 'f' + f((struct objc_object *)p); + ^ +t.mm:5:6: note: candidate function not viable: no known conversion from 'struct objc_object *' to 'id' for 1st argument +void f(id x); + ^ +</pre> + +<p>Code should use types <tt>id</tt>, <tt>SEL</tt>, and <tt>Class</tt> +instead of the internal types.</p> + +<!-- ======================================================================= --> +<h3 id="c_variables-class">C variables in @interface or @protocol</h3> +<!-- ======================================================================= --> + +<p>GCC allows the declaration of C variables in +an <code>@interface</code> or <code>@protocol</code> +declaration. Clang does not allow variable declarations to appear +within these declarations unless they are marked <code>extern</code>.</p> + +<p>Variables may still be declared in an @implementation.</p> + +<pre> +@interface XX +int a; // not allowed in clang +int b = 1; // not allowed in clang +extern int c; // allowed +@end + +</pre> + +<!-- ======================================================================= --> <h2 id="c++">C++ compatibility</h3> <!-- ======================================================================= --> @@ -250,8 +418,8 @@ compatibility with GNU C and C99 programs:</p> <ul> <li>The element type of a variable length array must be a POD ("plain old data") type, which means that it cannot have any - user-declared constructors or destructors, base classes, or any - members if non-POD type. All C types are POD types.</li> + user-declared constructors or destructors, any base classes, or any + members of non-POD type. All C types are POD types.</li> <li>Variable length arrays cannot be used as the type of a non-type template parameter.</li> </ul> @@ -260,12 +428,9 @@ template parameter.</li> </ul> <ol> <li>replace the variable length array with a fixed-size array if you can - determine a - reasonable upper bound at compile time; sometimes this is as + determine a reasonable upper bound at compile time; sometimes this is as simple as changing <tt>int size = ...;</tt> to <tt>const int size - = ...;</tt> (if the definition of <tt>size</tt> is a compile-time - integral constant);</li> -<li>use an <tt>std::string</tt> instead of a <tt>char []</tt>;</li> + = ...;</tt> (if the initializer is a compile-time constant);</li> <li>use <tt>std::vector</tt> or some other suitable container type; or</li> <li>allocate the array on the heap instead using <tt>new Type[]</tt> - @@ -273,46 +438,6 @@ template parameter.</li> </ul> </ol> <!-- ======================================================================= --> -<h3 id="init_static_const">Initialization of non-integral static const data members within a class definition</h3> -<!-- ======================================================================= --> - -The following code is ill-formed in C++'03: - -<pre> -class SomeClass { - public: - static const double SomeConstant = 0.5; -}; - -const double SomeClass::SomeConstant; -</pre> - -Clang errors with something similar to: - -<pre> -.../your_file.h:42:42: error: 'SomeConstant' can only be initialized if it is a static const integral data member - static const double SomeConstant = 0.5; - ^ ~~~ -</pre> - -Only <i>integral</i> constant expressions are allowed as initializers -within the class definition. See C++'03 [class.static.data] p4 for the -details of this restriction. The fix here is straightforward: move -the initializer to the definition of the static data member, which -must exist outside of the class definition: - -<pre> -class SomeClass { - public: - static const double SomeConstant; -}; - -const double SomeClass::SomeConstant<b> = 0.5</b>; -</pre> - -Note that the forthcoming C++0x standard will allow this. - -<!-- ======================================================================= --> <h3 id="dep_lookup">Unqualified lookup in templates</h3> <!-- ======================================================================= --> @@ -614,6 +739,18 @@ void Bar() { </pre> <!-- ======================================================================= --> +<h3 id="param_name_lookup">Parameter name lookup</h3> +<!-- ======================================================================= --> + +<p>Due to a bug in its implementation, GCC allows the redeclaration of function parameter names within a function prototype in C++ code, e.g.</p> +<blockquote> +<pre> +void f(int a, int a); +</pre> +</blockquote> +<p>Clang diagnoses this error (where the parameter name has been redeclared). To fix this problem, rename one of the parameters.</p> + +<!-- ======================================================================= --> <h2 id="objective-c++">Objective-C++ compatibility</h3> <!-- ======================================================================= --> @@ -622,18 +759,18 @@ void Bar() { <!-- ======================================================================= --> <p>Due to a bug in its implementation, GCC allows implicit downcasts -(from base class to a derived class) when calling functions. Such code is -inherently unsafe, since the object might not actually be an instance -of the derived class, and is rejected by Clang. For example, given -this code:</p> +of Objective-C pointers (from a base class to a derived class) when +calling functions. Such code is inherently unsafe, since the object +might not actually be an instance of the derived class, and is +rejected by Clang. For example, given this code:</p> <pre> @interface Base @end @interface Derived : Base @end -void f(Derived *); -void g(Base *base) { - f(base); +void f(Derived *p); +void g(Base *p) { + f(p); } </pre> @@ -641,11 +778,11 @@ void g(Base *base) { <pre> downcast.mm:6:3: error: no matching function for call to 'f' - f(base); + f(p); ^ downcast.mm:4:6: note: candidate function not viable: cannot convert from superclass 'Base *' to subclass 'Derived *' for 1st argument -void f(Derived *); +void f(Derived *p); ^ </pre> @@ -658,13 +795,17 @@ explicit cast:</p> </pre> <!-- ======================================================================= --> -<h3 id="Use of class as method name">Use of class as method name</h3> +<h3 id="class-as-property-name">Using <code>class</code> as a property name</h3> <!-- ======================================================================= --> -<p>Use of 'class' name to declare a method is allowed in objective-c++ mode to -be compatible with GCC. However, use of property dot syntax notation to call -this method is not allowed in clang++, as [I class] is a suitable syntax that -will work. So, this test will fail in clang++. +<p>In C and Objective-C, <code>class</code> is a normal identifier and +can be used to name fields, ivars, methods, and so on. In +C++, <code>class</code> is a keyword. For compatibility with existing +code, Clang permits <code>class</code> to be used as part of a method +selector in Objective-C++, but this does not extend to any other part +of the language. In particular, it is impossible to use property dot +syntax in Objective-C++ with the property name <code>class</code>, so +the following code will fail to parse:</p> <pre> @interface I { @@ -678,6 +819,7 @@ int cls; @end <pre> +<p>Use explicit message-send syntax instead, i.e. <code>[I class]</code>.</p> </div> </body> |