(→Restricted pointers) |
m |
||
(11 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{c title|C99}}{{C standards}} | ||
'''C99''' is a past version of the [[C programming language]] standard which was ratified by ISO in 1999 and became '''ISO/IEC 9899:1999'''. The same standard was later also adopted by ANSI on May 22, 2000. C99 cancels and replaces the first edition, [[C89]], and [[Normative Addendum 1|NA1]]. | '''C99''' is a past version of the [[C programming language]] standard which was ratified by ISO in 1999 and became '''ISO/IEC 9899:1999'''. The same standard was later also adopted by ANSI on May 22, 2000. C99 cancels and replaces the first edition, [[C89]], and [[Normative Addendum 1|NA1]]. | ||
Line 13: | Line 14: | ||
== New headers == | == New headers == | ||
− | C99 introduced 6 new [[C standard library|standard headers]]: | + | C99 introduced 6 new [[C standard library|standard headers]]: {{C|tgmath.h|<tgmath.h>}}, {{C|stdint.h|<stdint.h>}}, {{C|stdbool.h|<stdbool.h>}}, {{C|inttypes.h|<inttypes.h>}}, {{C|fenv.h|<fenv.h>}}, and {{C|complex.h|<complex.h>}}. |
== Restricted pointers == | == Restricted pointers == | ||
− | {{main| | + | {{main|c/restricted pointers|l1=Restricted pointers}} |
− | C99 introduced the concept of restricted pointer to the C language through the introduction of the ''' | + | C99 introduced the concept of restricted pointer to the C language through the introduction of the '''{{C|restrict}}''' {{C|reserved keywords|keyword}}. Given two pointers, if they do not point to two distinct objects, they are said to be ''aliases''. The ''restrict'' keyword establishes a special association between the pointer and the object it accesses, guaranteeing all accesses to the object it points to occur through that pointer or expressions based on that pointer. |
Since multiple pointers can point to the same object, compilers are often unable to make certain optimizations that require them to know that only a specific pointer has access to the object it points to. The restrict keyword was designed to aid such compiler issues. Consequently, various functions such as memcpy(), strcpy(), and strcat() have had their signatures changed to: | Since multiple pointers can point to the same object, compilers are often unable to make certain optimizations that require them to know that only a specific pointer has access to the object it points to. The restrict keyword was designed to aid such compiler issues. Consequently, various functions such as memcpy(), strcpy(), and strcat() have had their signatures changed to: | ||
Line 25: | Line 26: | ||
char *strcpy(char * restrict s1, const char * restrict s2); | char *strcpy(char * restrict s1, const char * restrict s2); | ||
char *strcat(char * restrict s1, const char * restrict s2); | char *strcat(char * restrict s1, const char * restrict s2); | ||
+ | </source> | ||
+ | |||
+ | == Variable-length array == | ||
+ | {{main|c/variable-length array|l1=Variable length arrays}} | ||
+ | '''Variable-length array''' ('''VLA''') are arrays of automatic storage whose size is determined at run-time. C99 introduced support for variable-length arrays. The length of the array does not change throughout the duration of the object's lifetime. | ||
+ | |||
+ | <source lang="C"> | ||
+ | int foo(size_t len) | ||
+ | { | ||
+ | int bar[len]; | ||
+ | something(bar); | ||
+ | return bar[0]; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Complex numbers == | ||
+ | {{main|c/complex numbers|l1=Complex numbers}} | ||
+ | C99 brought support for complex numbers including a set of functions for dealing with complex numbers which can be found in {{C|complex.h|<complex.h>}}. For example, | ||
+ | |||
+ | <source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | #include <complex.h> | ||
+ | int main() | ||
+ | { | ||
+ | double complex val = 4 * I; | ||
+ | val = cpow(val, 2); | ||
+ | printf("%f + %fi\n", creal(val), cimag(val)); | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Which outputs | ||
+ | -16.000000 + 0.000000i | ||
+ | |||
+ | == Type-generic math == | ||
+ | {{main|c/tgmath.h|l1=<tgmath.h>}} | ||
+ | C99 introduce the {{C|tgmath.h|<tgmath.h>}} header which provide {{C|generic selection|type-generic macros}} that determine the function depending on the arguments provided. | ||
+ | |||
+ | == Extended identifiers == | ||
+ | {{main|c/extended identifiers|l1=Extended identifiers}} | ||
+ | C99 brought support for extended identifiers and extended characters. For example: | ||
+ | |||
+ | <source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | void שלום() { puts("Hello"); } | ||
+ | int main() | ||
+ | { | ||
+ | שלום(); | ||
+ | \u05E9\u05DC\u05D5\u05DD(); | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Compound literal == | ||
+ | {{main|c/compound literals|l1=compound literals}} | ||
+ | A compound literal is a postfix expression that provides an unnamed object whose value is given by the initializer list. Such expressions may be const as well. Compound literals take the form <code>(type-name){initializer-list}</code>. For example, | ||
+ | |||
+ | <source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | int main() | ||
+ | { | ||
+ | char *p = (char[]){"string"}; | ||
+ | p[2] = '@'; | ||
+ | p = (char[100]){0}; | ||
+ | strcpy(p, "example"); | ||
+ | puts(p); | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Designated initializers == | ||
+ | {{main|c/designated initializers|l1=designated initializers}} | ||
+ | '''Designated initializers''' are a feature added in C99 that allows a particular element to be initialized. Designated initializers are supported for {{C|arrays}}, {{C|structures|structs}}, and {{C|unions}}. For example: | ||
+ | |||
+ | <source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | enum bosses { aquamentus, dodongo, manhandla, gleeok }; | ||
+ | struct boss | ||
+ | { | ||
+ | const char *name; | ||
+ | const char *weapon[5]; | ||
+ | } | ||
+ | boss_list[] = | ||
+ | { | ||
+ | [aquamentus] = { .weapon = { [1] = "bombs", [0] = "sword", [2] = 0 }, .name = "aquamentus"}, | ||
+ | [dodongo] = { .weapon = { [0] = "bombs", [1] = "sword", [2] = 0 }, .name = "dodongo" }, | ||
+ | [manhandla] = { .weapon = { [0] = "bombs", [1] = "sword", [2] = 0 }, .name = "manhandla" }, | ||
+ | [gleeok] = { .weapon = { [0] = "bombs", [2] = 0, [1] = "sword" }, .name = "gleeok"} | ||
+ | }; | ||
+ | int main() | ||
+ | { | ||
+ | printf("%s -> %s\n", boss_list[manhandla].name, boss_list[manhandla].weapon[0]); | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Single-line comments == | ||
+ | C99 introduced the <code>//</code> notation for single-line comments. Single-line comments start with two [[slashes]] and terminate at the end of the line. | ||
+ | <source lang="C">// this is a comment</source> | ||
+ | |||
+ | == Extended integer types == | ||
+ | {{main|c/extended integer types|l1=Extended integer types}} | ||
+ | Starting with C99, extended integer types were added to the C programming language. Extended integer types, which come in pairs of signed and unsigned types, are defined by the implementation in a manner they choose. They must obey the same standard integer rules but their names is up to the implementation, for example: | ||
+ | |||
+ | <source lang="C"> | ||
+ | long long long int x = 333333; | ||
+ | __int128 y = 123; | ||
+ | </source> | ||
+ | |||
+ | == Mixed declarations and code == | ||
+ | C99 relaxed the restrictions that required declarations to be at the beginning of a code block. Starting with C99, declarations and code may be mixed. | ||
+ | |||
+ | == Variadic macros == | ||
+ | C99 added support for variadic macros. The new <code>__VA_ARGS__</code> preprocessor keyword must only be used within the replacement list of a function-like macro that uses the ellipsis notation in the arguments. For example: | ||
+ | |||
+ | <source lang="C"> | ||
+ | #define debug(...) fprintf(stderr, __VA_ARGS__) | ||
+ | debug("Hello World!\n"); | ||
+ | debug("Hello %s!\n", "Bob"); | ||
+ | </source> | ||
+ | |||
+ | == inline functions == | ||
+ | {{main|c/inline functions|l1=inline functions}} | ||
+ | Support for inline functions were added in C99. | ||
+ | |||
+ | == boolean types == | ||
+ | {{main|c/stdbool.h|l1=<stdbool.h>}} | ||
+ | C99 introduced a new boolean type with the <code>_Bool</code> keyword. A set of convenient macros are defined in the {{C|stdbool.h|<stdbool.h>}} header. | ||
+ | |||
+ | <source lang="C"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdbool.h> | ||
+ | int main(void) | ||
+ | { | ||
+ | bool foo = true; | ||
+ | if (foo) | ||
+ | puts("It's true!"); | ||
+ | return 0; | ||
+ | } | ||
</source> | </source> | ||
Line 38: | Line 180: | ||
| ACK || style="background:#FF6666;text-align:center;" | No Support || || | | ACK || style="background:#FF6666;text-align:center;" | No Support || || | ||
|- | |- | ||
− | | Clang || style="background:#99FF66;text-align:center;" | Complete || style="text-align:center;" | -std=c99 || | + | | Clang || style="background:#99FF66;text-align:center;" | Complete || style="text-align:center;" | -std=c99 || Supports everything<ref>[http://p99.gforge.inria.fr/c99-conformance/c99-conformance-clang-3.2.html C99 Conformance CLANG Test]</ref> |
|- | |- | ||
| GCC || style="background:#99FF66;text-align:center;" | Complete || style="text-align:center;" | -std=c99 || Supports everything<ref>[http://p99.gforge.inria.fr/c99-conformance/c99-conformance-gcc-4.7.html C99 Conformance GCC Test]</ref> | | GCC || style="background:#99FF66;text-align:center;" | Complete || style="text-align:center;" | -std=c99 || Supports everything<ref>[http://p99.gforge.inria.fr/c99-conformance/c99-conformance-gcc-4.7.html C99 Conformance GCC Test]</ref> | ||
Line 52: | Line 194: | ||
{{reflist}} | {{reflist}} | ||
− | [ | + | == External links == |
+ | * [http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf C99 with Technical Corrigendum included] | ||
+ | |||
[[Category:C standards]] | [[Category:C standards]] |
Latest revision as of 08:24, 4 January 2015
C99 is a past version of the C programming language standard which was ratified by ISO in 1999 and became ISO/IEC 9899:1999. The same standard was later also adopted by ANSI on May 22, 2000. C99 cancels and replaces the first edition, C89, and NA1.
C99 brought the first major updates to the language in a decade. The new standard introduced restricted pointers, variable-length arrays, flexible array members, complex numbers support, type-generic math, long long int
, extended identifiers, hexadecimal floating-point constants, compound literals, designated initializers, single line, //
comments, extended integer type, the ability to mix declarations and code, variadic macros, new math functions, inline functions, boolean types, _Pragma and standard pragmas, and VA_COPY. The standard also removed implicit function declaration.
Contents
- 1 Version detection
- 2 New headers
- 3 Restricted pointers
- 4 Variable-length array
- 5 Complex numbers
- 6 Type-generic math
- 7 Extended identifiers
- 8 Compound literal
- 9 Designated initializers
- 10 Single-line comments
- 11 Extended integer types
- 12 Mixed declarations and code
- 13 Variadic macros
- 14 inline functions
- 15 boolean types
- 16 Compiler support
- 17 References
- 18 External links
Version detection[edit]
C99 can be detected via the __STDC_VERSION__ mandatory macro which must equal 199901L
.
#if __STDC_VERSION__ >= 199901L
/* C99 support */
#endif
New headers[edit]
C99 introduced 6 new standard headers: <tgmath.h>, <stdint.h>, <stdbool.h>, <inttypes.h>, <fenv.h>, and <complex.h>.
Restricted pointers[edit]
- Main article: Restricted pointers
C99 introduced the concept of restricted pointer to the C language through the introduction of the restrict keyword. Given two pointers, if they do not point to two distinct objects, they are said to be aliases. The restrict keyword establishes a special association between the pointer and the object it accesses, guaranteeing all accesses to the object it points to occur through that pointer or expressions based on that pointer.
Since multiple pointers can point to the same object, compilers are often unable to make certain optimizations that require them to know that only a specific pointer has access to the object it points to. The restrict keyword was designed to aid such compiler issues. Consequently, various functions such as memcpy(), strcpy(), and strcat() have had their signatures changed to:
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
char *strcpy(char * restrict s1, const char * restrict s2);
char *strcat(char * restrict s1, const char * restrict s2);
Variable-length array[edit]
- Main article: Variable length arrays
Variable-length array (VLA) are arrays of automatic storage whose size is determined at run-time. C99 introduced support for variable-length arrays. The length of the array does not change throughout the duration of the object's lifetime.
int foo(size_t len)
{
int bar[len];
something(bar);
return bar[0];
}
Complex numbers[edit]
- Main article: Complex numbers
C99 brought support for complex numbers including a set of functions for dealing with complex numbers which can be found in <complex.h>. For example,
#include <stdio.h>
#include <complex.h>
int main()
{
double complex val = 4 * I;
val = cpow(val, 2);
printf("%f + %fi\n", creal(val), cimag(val));
return 0;
}
Which outputs
-16.000000 + 0.000000i
Type-generic math[edit]
- Main article: <tgmath.h>
C99 introduce the <tgmath.h> header which provide type-generic macros that determine the function depending on the arguments provided.
Extended identifiers[edit]
- Main article: Extended identifiers
C99 brought support for extended identifiers and extended characters. For example:
#include <stdio.h>
void שלום() { puts("Hello"); }
int main()
{
שלום();
\u05E9\u05DC\u05D5\u05DD();
return 0;
}
Compound literal[edit]
- Main article: compound literals
A compound literal is a postfix expression that provides an unnamed object whose value is given by the initializer list. Such expressions may be const as well. Compound literals take the form (type-name){initializer-list}
. For example,
#include <stdio.h>
#include <string.h>
int main()
{
char *p = (char[]){"string"};
p[2] = '@';
p = (char[100]){0};
strcpy(p, "example");
puts(p);
return 0;
}
Designated initializers[edit]
- Main article: designated initializers
Designated initializers are a feature added in C99 that allows a particular element to be initialized. Designated initializers are supported for arrays, structs, and unions. For example:
#include <stdio.h>
#include <string.h>
enum bosses { aquamentus, dodongo, manhandla, gleeok };
struct boss
{
const char *name;
const char *weapon[5];
}
boss_list[] =
{
[aquamentus] = { .weapon = { [1] = "bombs", [0] = "sword", [2] = 0 }, .name = "aquamentus"},
[dodongo] = { .weapon = { [0] = "bombs", [1] = "sword", [2] = 0 }, .name = "dodongo" },
[manhandla] = { .weapon = { [0] = "bombs", [1] = "sword", [2] = 0 }, .name = "manhandla" },
[gleeok] = { .weapon = { [0] = "bombs", [2] = 0, [1] = "sword" }, .name = "gleeok"}
};
int main()
{
printf("%s -> %s\n", boss_list[manhandla].name, boss_list[manhandla].weapon[0]);
return 0;
}
Single-line comments[edit]
C99 introduced the //
notation for single-line comments. Single-line comments start with two slashes and terminate at the end of the line.
// this is a comment
Extended integer types[edit]
- Main article: Extended integer types
Starting with C99, extended integer types were added to the C programming language. Extended integer types, which come in pairs of signed and unsigned types, are defined by the implementation in a manner they choose. They must obey the same standard integer rules but their names is up to the implementation, for example:
long long long int x = 333333;
__int128 y = 123;
Mixed declarations and code[edit]
C99 relaxed the restrictions that required declarations to be at the beginning of a code block. Starting with C99, declarations and code may be mixed.
Variadic macros[edit]
C99 added support for variadic macros. The new __VA_ARGS__
preprocessor keyword must only be used within the replacement list of a function-like macro that uses the ellipsis notation in the arguments. For example:
#define debug(...) fprintf(stderr, __VA_ARGS__)
debug("Hello World!\n");
debug("Hello %s!\n", "Bob");
inline functions[edit]
- Main article: inline functions
Support for inline functions were added in C99.
boolean types[edit]
- Main article: <stdbool.h>
C99 introduced a new boolean type with the _Bool
keyword. A set of convenient macros are defined in the <stdbool.h> header.
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
bool foo = true;
if (foo)
puts("It's true!");
return 0;
}
Compiler support[edit]
Support for C99 has been a slow ongoing effort.
C99 Compiler Support | |||
Compiler Name | Support Level | Enforcement Switch | Note |
---|---|---|---|
ACK | No Support | ||
Clang | Complete | -std=c99 | Supports everything[1] |
GCC | Complete | -std=c99 | Supports everything[2] |
TCC | Partial | Missing lots of features[3] | |
ICC | Partial | -std=c99 | Broken extended identifier support, broken inline function support[4] |
Visual C++ | Partial | Missing type-generic math[5] |