Privacy Policy Cookie Policy Terms and Conditions C syntax - Wikipedia, the free encyclopedia

C syntax

From Wikipedia, the free encyclopedia

The syntax of the C programming language is a set of rules that specifies whether the sequence of characters in a file is conforming C source code. The rules specify how the character sequences are to be chunked into tokens (the lexical grammar), the permissible sequences of these tokens and some of the meaning to be attributed to these permissible token sequences (additional meaning is assigned by the semantics of the language).

C syntax makes use of the maximal munch principle.

Contents

[edit] Data structures

[edit] Numeric data types

Many programming languages, including C, represent numbers in two forms: integral and real (or "floating point"). This distinction reflects similar distinctions in the instruction set architecture of most central processing units.

The basic integral specifier is int; it is used to denote the representation of integers. The integral types come in different sizes, with varying amounts of memory usage and range of representable magnitude[1]. Modifiers are used to designate the size: short, long and long long[2]. The character type, whose specifier is char, represents the smallest addressable storage unit, which is often an 8-bit byte.

The floating-point form is used to represent numbers with a fractional component. They do not however represent most rational numbers exactly; they are a close approximation instead. There are three types of real values, denoted by their specifier: single-precision (specifier float), double-precision (double) and double-extended-precision (long double). Each of these may represent values in a different form.

Integral types can be either signed (which is implied when not specified) or unsigned. However char, signed char and unsigned char are all different types, and for historic reasons plain char may be signed or unsigned.

When signed, one bit of the representation of the integer in memory may instead be used to represent sign (positive or negative). For example, a signed 16-bit integer may use one bit for its sign and the remaining 15 bits for the representation of its value. (Other allowed integer representations are two's complement and ones' complement.) When unsigned, there is no sign bit; all bits are used to represent the magnitude.


[1] In terms of integral values, magnitude represents the value (independent of sign).

[2] The long long modifier was introduced in the C99 standard; some compilers had already supported it.

[edit] Constants that define limits of numeric data types

The standard header file limits.h defines the minimum and maximum values of the integral primitive data types, amongst other limits. The standard header file float.h defines the minimum and maximum values of the floating-point types float, double, and long double. It also defines other limits that are relevant to the processing of floating-point numbers.

Limits of integral types
Implicit Specifier(s) Explicit Specifier LM[1] Minimum Value Maximum Value
char signed char or unsigned char[2] none CHAR_MIN CHAR_MAX
signed char signed char none SCHAR_MIN SCHAR_MAX
unsigned char unsigned char none 0 UCHAR_MAX
short signed short int none SHRT_MIN SHRT_MAX
unsigned short unsigned short int none 0 USHRT_MAX
none[3], signed, or int signed int none INT_MIN INT_MAX
unsigned unsigned int U 0 UINT_MAX
long signed long int L LONG_MIN LONG_MAX
unsigned long unsigned long int UL 0 ULONG_MAX
long long[4] signed long long int LL LLONG_MIN LLONG_MAX
unsigned long long[4] unsigned long long int ULL 0 ULLONG_MAX

1. LM = Literal Modifier, the characters that are appended to an integer literal which allow it to represent values beyond the scope of the signed int type.
2. Standard C does not mandate whether the char type should be signed or unsigned; its status as such depends upon the compiler.
3. As of C99, the omission of any specifier to imply the int type is no longer supported.
4. Support for the long long type was introduced with C99. The accompanying symbols and literal modifiers will only be available on compliant compilers.

[edit] Typical limits of integral types

The following tables provides a list of the integral types and their typical storage sizes and acceptable ranges of values, which may vary from one implementation to another. For the purposes of this table, the char type is omitted; refer to the appropriate analogue, signed char or unsigned char. For integral types of guaranteed sizes, ranging from 8 to 64 bits, ISO C provides the inttypes.h header.

Typical limits of integral types
Implicit Specifier(s) Explicit Specifier Bits Bytes Minimum Value Maximum Value
signed char same 8 1 −128 127
unsigned char same 8 1 0 255
short signed short int 16 2 −32,768 32,767
unsigned short unsigned short int 16 2 0 65,535
long signed long int 32 4 −2,147,483,648 2,147,483,647
unsigned long unsigned long int 32 4 0 4,294,967,295
long long[1] signed long long int 64 8 −9,223,372,036,854,775,808 9,223,372,036,854,775,807
unsigned long long[1] unsigned long long int 64 8 0 18,446,744,073,709,551,615

1. Support for the long long type was introduced with C99.

The size and limits of the plain int type (without the short, long, or long long modifiers) vary much more than the other integral types among C implementations. The Single UNIX Specification specifies that the int type must be at least 32 bits, but the ISO C standard only requires 16 bits.

[edit] Pointers

In declarations the asterisk modifier (*) specifies a pointer type. For example, where the specifier int would refer to the integral type, the specifier int * refers to the type "pointer to integer". Pointer values associate two pieces of information: a memory address and a data type. The following line of code declares a pointer-to-integer variable called ptr:

int *ptr;

[edit] Referencing

When a non-static pointer is declared, it has an unspecified value associated with it. The address associated with such a pointer must be changed by assignment prior to using it. In the following example, ptr is set so that it points to the data associated with the variable a:

int *ptr;
int a;

ptr = &a;

In order to accomplish this, the "address-of" operator (unary &) was used. It produces the memory location of the data object that follows.

[edit] Dereferencing

The pointed-to data can be accessed through a pointer value. In the following example, the integral variable b is set to the value 10:

int *ptr;
int a, b;

a = 10;
ptr = &a;
b = *ptr;

In order to accomplish that task, the dereference operator (unary *) was used. It returns the data to which its operand—which must be of pointer type—points. Thus, the expression *ptr denotes the same value as a.

[edit] Arrays

[edit] Array declaration

Arrays are used in C to represent structures of consecutive elements of the same type. The declaration of a (fixed-size) array has the following syntax:

int array[100];

which defines an array named array to hold 100 values of the primitive type int. When using a C99-conforming compiler, the array dimension may also be a non-constant expression (if declared within a function), in which case memory for the specified number of elements will be allocated. The variable array decays to the reference integral type in most expression contexts (operand of sizeof being the main exception); the value obtained from that decay points to the memory address of the first element.

[edit] Accessing elements

The primary facility for accessing the values of the elements of an array is the array subscript operator. To access the i-indexed element of array, the syntax would be array[i], which refers to the value stored in that array element.

Array subscript numbering begins at 0. The largest allowed array subscript is therefore equal to the number of elements in the array minus 1. To illustrate this, consider an array a declared as having 10 elements; the first element would be a[0] and the last element would be a[9]. C provides no facility for automatic bounds checking for array usage. Though logically the last subscript in an array of 10 elements would be 9, subscripts 10, 11, and so forth could accidentally be specified, with undefined results.

Due to array↔pointer interchangeability, the addresses of each of the array elements can be expressed in equivalent pointer arithmetic. The following table illustrates both methods for the existing array:

Array subscripts vs. pointer arithmetic
Element index 0 1 2 n
Array subscript array[0] array[1] array[2] array[n]
Dereferenced pointer *array *(array + 1) *(array + 2) *(array + n)

[edit] Dynamic arrays

Recall that a constant is required for the dimension in a declaration of a static array. Often we would prefer to determine the array length as a run-time variable:

int a[n];
a[3] = 10;

This behavior can be imitated with the help of the C standard library. The malloc function provides a simple method for allocating memory. It takes one parameter: the amount of memory to allocate in bytes. Upon successful allocation, malloc returns a generic (void *) pointer value, pointing to the beginning of the allocated space. The pointer value returned is converted to an appropriate type implicitly by assignment. If the allocation could not be completed, malloc returns a null pointer. The following segment is therefore similar in function to the above desired declaration:

#include <stdlib.h> /* declares malloc */
…
int *a;
a = malloc(n * sizeof(int));
a[3] = 10;

The result is a "pointer to int" variable (a) that points to the first of n contiguous int objects; due to array↔pointer equivalence this can be used in place of an actual array name, as shown in the last line. The advantage in using this dynamic allocation is that the amount of memory that is allocated to it can be limited to what is actually needed at run time, and this can be changed as needed (using the standard library function realloc).

When the dynamically-allocated memory is no longer needed, it should be released back to the run-time system. This is done with a call to the free function. It takes a single parameter: a pointer to previously allocated memory. This is the value that was returned by the call to malloc. It is sometimes useful to then set the pointer variable to NULL so that further attempts to access the memory to which it points will fail.

free(a);
a = NULL;

[edit] Multidimensional arrays

In addition, C supports arrays of multiple dimensions, which are stored in row-major order. Technically, C multidimensional arrays are just one-dimensional arrays whose elements are arrays. The syntax for declaring multidimensional arrays is as follows:

int array2d[ROWS][COLUMNS];

(where ROWS and COLUMNS are constants); this defines a two-dimensional array. Reading the subscripts from left to right, array2d is an array of length ROWS, each element of which is an array of COLUMNS ints.

To access an integer element in this multidimensional array, one would use

array2d[4][3]

Again, reading from left to right, this accesses the 5th row, 4th element in that row. (Note that array2d[4] itself denotes an array, which we are then subscripting with the [3] to access the integer.)

Higher-dimensional arrays can be declared in a similar manner.

A multidimensional array should not be confused with an array of references to arrays (also known as Iliffe vectors or sometimes array of arrays). The former is always rectangular (all subarrays must be the same size), and occupies a contiguous region of memory. The latter is a one-dimensional array of pointers, each of which may point to the first element of a subarray in a different place in memory, and the subarrays do not have to be the same size. The latter can be created by multiple use of malloc.

[edit] Strings

In C, string literals (constants) are surrounded by double quotes ("), e.g. "Hello world!" and are compiled to an array of the specified char values with an additional null (0-valued) code to mark the end of the string. If you wish to include a double quote inside the string, that can be done by escaping it with a backslash (\), for example, "This string contains \"double quotes\".". To insert a literal backslash, one must double it, e.g. "A backslash looks like this: \\".

Backslashes may be used to enter control characters, etc., into a string:

Escape Meaning
\\ Literal backslash
\" Double quote
\' Single quote
\n Newline (line feed)
\r Carriage return
\b Backspace
\t Horizontal tab
\f Form feed
\a Alert (bell)
\v Vertical tab
\? Question mark (used to escape trigraphs)
\nnn Character with octal value nnn
\xhh Character with hexadecimal value hh

The use of other backslash escapes is not defined by the C standard.

Individual character constants are represented by single-quotes, e.g. 'A', and have type int (not char). The difference is that "A" represents a pointer to the first element of a null-terminated array, whereas 'A' directly represents the code value (65 if ASCII is used). The same backslash-escapes are supported as for strings, except that (of course) " can validly be used as a character without being escaped, whereas ' must now be escaped. A character constant cannot be empty (i.e. '' is invalid syntax), although a string may be (it still has the null-byte terminator). Multi-character constants (e.g. 'xy') are valid, although rarely useful — they let one store several characters in an integer (e.g. 4 ASCII characters can fit in a 32-bit integer, 8 in a 64-bit one). Since the order in which the characters are packed into one int are not specified, portable use of multi-character constants is difficult.

There are several standard library functions for operating with string data (not necessarily constant) organized as array of char using this null-terminated format; see below.

C's string-literal syntax has been very influential, and has made its way into many other languages, such as C++, Perl, Python, PHP, Java, Javascript, C#, Ruby. Nowadays, almost all new languages adopt or build upon C-style string syntax; languages which lack this syntax tend to preceed C.

[edit] Wide character strings

For historical reasons, type char typically can represent at most 255 distinct character codes, not nearly enough for all the characters in use worldwide. To provide better support for international characters, the first C standard (C89) introduced wide characters (encoded in type wchar_t) and wide character strings, which are written as L"Hello world!"

Wide characters are most commonly either 2 bytes (UTF-16) or 4 bytes (UTF-32), but Standard C does not specify the width for wchar_t, leaving the choice to the implementor. Microsoft Windows generally uses UTF-16, thus the above string would be 26 bytes long for a Microsoft compiler; the Unix world prefers UTF-32, thus compilers such as GCC would generate a 52-byte string.

The original C standard specified only minimal functions for operating with wide character strings; in 1995 the standard was modified to include much more extensive support, comparable to that for the legacy char arrays.

[edit] Library functions

strings, both constant and variable, may be manipulated without using the standard library. However, the library contains many useful functions for working with null-terminated strings. It is the programmer's responsibility to ensure that enough storage has been allocated to hold the resulting strings.

The most commonly used string functions are:

  • strcat(dest, source) - appends the string source to the end of string dest
  • strchr(s, c) - finds the first instance of character c in string s and returns a pointer to it or a null pointer if c is not found
  • strcmp(a, b) - compares strings a and b (lexicographical ordering); returns negative if a is less than b, 0 if equal, positive if greater.
  • strcpy(dest, source) - copies the string source onto the string dest
  • strlen(st) - return the length of string st
  • strncat(dest, source, n) - appends a maximum of n characters from the string source to the end of string dest and null terminates the string at the end of input or at index n+1 when the max length is reached
  • strncmp(a, b, n) - compares a maximum of n characters from strings a and b (lexical ordering); returns negative if a is less than b, 0 if equal, positive if greater
  • strrchr(s, c) - finds the last instance of character c in string s and returns a pointer to it or a null pointer if c is not found

Other standard string functions include:

  • strcoll(s1, s2) - compare two strings according to a locale-specific collating sequence
  • strcspn(s1, s2) - returns the index of the first character in s1 that matches any character in s2
  • strerror(errno) - returns a string with an error message corresponding to the code in errno
  • strncpy(dest, source, n) - copies n characters from the string source onto the string dest, substituting null bytes once past the end of source; does not null terminate if max length is reached
  • strpbrk(s1, s2) - returns a pointer to the first character in s1 that matches any character in s2 or a null pointer if not found
  • strspn(s1, s2) - returns the index of the first character in s1 that matches no character in s2
  • strstr(st, subst) - returns a pointer to the first occurrence of the string subst in st or a null pointer if no such substring exists
  • strtok(s1, s2) - returns a pointer to a token within s1 delimited by the characters in s2
  • strxfrm(s1, s2, n) - transforms s2 onto s1, such that s1 used with strcmp gives the same results as s2 used with strcoll

There is a similar set of functions for handling wide character strings.

[edit] Operators

Main article: Operators in C and C++

[edit] Control structures

Basically, C is a free-form language.

Note: bracing style varies from programmer to programmer and can be the subject of great debate ("flame wars"). See Indent style for more details.

[edit] Compound statements

Compound statements in C have the form

  { <optional-declaration-list> <optional-statement-list> }

and are used as the body of a function or anywhere that a single statement is expected.

[edit] Expression statements

A statement of the form

  <optional-expression> ;

is an expression statement. If the expression is missing, the statement is called a null statement.

[edit] Selection statements

C has three types of selection statements: two kinds of if and the switch statement.

The two kinds of if statement are

  if (<expression>)
     <statement>

and

  if (<expression>)
     <statement>
  else
     <statement>

In the if statement, if the expression in parentheses is nonzero (true), control passes to the statement following the if. If the else clause is present, control will pass to the statement following the else when the expression in parentheses is zero (false). An else always matches the nearest previous unmatched if; braces may be used to override this when necessary, or for clarity.

The switch statement causes control to be transferred to one of several statements depending on the value of an expression, which must have integral type. The substatement controlled by a switch is typically compound. Any statement within the substatement may be labeled with one or more case labels, which consist of the keyword case followed by a constant expression and then a colon (:). No two of the case constants associated with the same switch may have the same value. There may be at most one default label associated with a switch; if none of the case labels are equal to the expression in the parentheses following switch, control passes to the default label, or if there is no default label, execution resumes just beyond the entire construct. Switches may be nested; a case or default label is associated with the innermost switch that contains it. Switch statements can "fall through", that is, when one case section has completed its execution, statements will continue to be executed downward until a break; statement is encountered. Fall-through is useful in some circumstances, but is usually not desired. In the below example, if <label2> is reached, the statements <statements 2> are executed and nothing more inside the braces. However if <label1> is reached, both <statements 1> and <statements 2> are executed since there is no break to separate the two case statements.

  switch (<expression>) {
     case <label1> :
        <statements 1>
     case <label2> :
        <statements 2>
        break;
     default :
        <statements 3>
  }

[edit] Iteration statements

C has three forms of iteration statement:

  do
     <statement>
  while ( <expression> ) ;
  while ( <expression> )
     <statement>

C89's for loop

  for ( <expression> ; <expression> ; <expression> )
     <statement> 

was generalized in C99 to

  for ( <clause> ; <expression> ; <expression> )
     <statement> 

with <clause> being the initialization part of the loop (an expression or a declaration).

In the while and do statements, the substatement is executed repeatedly so long as the value of the expression remains nonzero (true). With while, the test, including all side effects from the expression, occurs before each execution of the statement; with do, the test follows each iteration.

If all three expressions are present in a for, the statement

  for (e1; e2; e3)
     s;

is equivalent to

  e1;
  while (e2) {
     s;
     e3;
  }

except for the behavior of a continue; statement (which jumps to e3 instead of e2).

Any of the three expressions in the for loop may be omitted. A missing second expression makes the while test always nonzero, creating a potentially infinite loop.

[edit] Jump statements

Jump statements transfer control unconditionally. There are four types of jump statements in C: goto, continue, break, and return.

The goto statement looks like this:

  goto <identifier>;

The identifier must be a label (followed by a colon) located in the current function. Control transfers to the labeled statement.

A continue statement may appear only within an iteration statement and causes control to pass to the loop-continuation portion of the innermost enclosing iteration statement. That is, within each of the statements

  while (expression) {
     /* ... */
     cont: ;
  }
  do {
     /* ... */
     cont: ;
  } while (expression);
  for (expr1; expr2; expr3) {
     /* ... */
     cont: ;
  }   

a continue not contained within a nested iteration statement is the same as goto cont.

The break statement is used to end a for loop, while loop, do loop, or switch statement. Control passes to the statement following the terminated statement.

A function returns to its caller by the return statement. When return is followed by an expression, the value is returned to the caller as the value of the function. Encountering the end of the function is equivalent to a return with no expression. In that case, if the function is declared as returning a value and the caller tries to use the returned value, the result is undefined.

[edit] Storing the address of a label

GCC extends the C language with a unary && operator that returns the address of a label. This address can be stored in a void* variable type and may be used later in a goto instruction. For example, the following prints "hi " in an infinite loop:

    void *ptr = &&J1;

J1: printf("hi ");
    goto *ptr;

[edit] Functions

[edit] Syntax

A C function definition consists of a return type (void if no value is returned), a unique name, a list of parameters in parentheses, (void if there are none), and various statements at least one of which should be a return statement (again, if the return type is void an explicit return might not be needed):

 <return-type> functionName( <parameter-list> )
 {
    <statements>
    
    return <expression of type return-type>;
 }

where <parameter-list> of n variables is declared as data type and variable name separated by a comma:

 <data-type> var1, <data-type> var2, ... <data-type> varN

[edit] Example

Example of a program that adds two integers and prints: 1 + 1 = 2

 #include <stdio.h>
 
 int add(int x, int y)
 {
    return x + y;
 }
 
 int main(void)
 {
    int foo = 1, bar = 1;
    printf("%d + %d = %d\n", foo, bar, add(foo, bar));
    return 0;
 }

The function main must be declared as having an int return type according to the C standard. It returns 0, indicating success, to its caller, typically the underlying operating system.

[edit] Global structure

After preprocessing, at the highest level a C program consists of a sequence of declarations at file scope. These may be partitioned into several separate source files, which may be compiled separately; the resulting object modules are then linked along with implementation-provided run-time support modules to produce an executable image.

The declarations introduce functions, variables and types. C functions are akin to the subroutines of Fortran or the procedures of Pascal.

A definition is a special type of declaration. A variable definition sets aside storage and possibly initializes it, a function definition provides its body.

An implementation of C providing all of the standard library functions is called a hosted implementation. Programs written for hosted implementations are required to define a special function called main, which is the first function called when execution of the program begins. Here is a minimal C program:

 int main(void)
 {
    return 0;
 }

The main function will usually call other functions to help it perform its job.

Some implementations are not hosted, usually because they are not intended to be used with an operating system. Such implementations are called free-standing in the C standard. A free-standing implementation is free to specify how it handles program startup; in particular it need not require a program to define a main function.

Functions may be written by the programmer or provided by existing libraries. Interfaces for the latter are usually declared by including header files—with the #include preprocessing directive—and the library objects are linked into the final executable image. Certain library functions, such as printf, are defined by the C standard; these are referred to as the standard library functions.

A function may return a value to the environment that called it. This is usually another C function; however, the calling environment of the main function is the parent process in Unix-like systems or the operating system itself in other cases. By definition, the return value zero (or the value of the EXIT_SUCCESS macro) from main signifies successful completion of the program. (There is also an EXIT_FAILURE macro to signify failure.) The printf function mentioned above returns how many characters were printed, but this value is often ignored.

[edit] Passing variables

In C, arguments are passed to functions by value while other languages may pass variables by reference. This means that the receiving function gets copies of the values and has no direct way of altering the original variables. For a function to alter a variable passed from another function, the caller must pass its address (a pointer to it), which can then be dereferenced in the receiving function (see Pointers for more info):

 void incInt(int *y)
 {
    (*y)++;  // Increase the value of 'x', in main, by one
 }

 int main(void)
 {
    int x = 0;
    incInt(&x);  // pass a reference to the var 'x'
    return 0;
 }

The function scanf works the same way:

 int x;
 scanf("%d", &x);

In order to pass an editable pointer to a function you have to pass a pointer to that pointer; its address:

 void setInt(int **p, int n)
 {
    *p = (int *) malloc(sizeof(int));    // allocate a memory area, saving the pointer in the
                                         // location pointed to by the parameter "p"
    
    // dereference the given pointer that has been assigned an address
    // of dynamically allocated memory and set the int to the value of n (42)    
    **p = n;                             
 }

 int main(void)
 {
    int *p;           // create a pointer to an integer
    setInt(&p, 42);   // pass the address of 'p'
    return 0;
 }

int **p defines a pointer to a pointer, which is the address to the pointer p in this case.

[edit] Input/Output

In C, input and output are performed via a group of functions in the standard library. In ISO C, those functions are defined in the <stdio.h> header.

[edit] Standard I/O

Three standard I/O streams are predefined:

These streams are automatically opened and closed by the runtime environment, they need not and should not be opened explicitly.

The following example demonstrates how a filter program is typically structured:


#include <stdio.h>

int main(void)
{
   int c;

   while ((c = getchar()) != EOF ) 
   {
         /* do various things
            to the characters */

          if (anErrorOccurs) {
              fputs("An error occurred\n", stderr);
              break;
          }

         /* ... */
         putchar(c);
         /* ... */

    }
    return 0;
}

[edit] File I/O

[edit] Miscellaneous

[edit] Case sensitivity

C is case sensitive. Some linkers may map external identifiers to a single case, although this is uncommon these days.

[edit] Comments

Text starting with /* is treated as a comment and ignored. The comment ends at the next */ and can span multiple lines. Accidental omission of the comment terminator is problematic in that the next comment's properly constructed comment terminator will be used to terminate the initial comment, and all code in between the comments will be considered as a comment.

The C99 standard introduced C++ style line comments. These start with // and extend to the end of the line.

 // this line will be ignored by the compiler

 /* these lines
    will be ignored
    by the compiler */

[edit] Command-line arguments

The parameters given on a command line are passed to a C program with two predefined variables - the count of the command-line arguments in argc and the individual arguments as character strings in the pointer array argv. So the command

 myFilt p1 p2 p3

results in something like

Image:CCommandLineArgv.png

(Note: While individual strings are contiguous arrays of char, there is no guarantee that the strings are stored as a contiguous group.)

The name of the program, argv[0], may be useful when printing diagnostic messages. The individual values of the parameters may be accessed with argv[1], argv[2], and argv[3], as shown in the following program:

#include <stdio.h>

int main(int argc, char *argv[])
{
  int i;
  printf ("argc\t= %i\n", argc);
  for (i = 0; i < argc; i++)
    printf ("argv[%i]\t= %s\n", i, argv[i]);
  return 0;
}

[edit] Evaluation order

A conforming C compiler can evaluate expressions in any order between sequence points. Sequence points are defined by:

  • Statement ends at semicolons.
  • The sequencing operator: a comma.
  • The short-circuit operators: logical and (&&) and logical or (||).
  • The conditional operator (?:): This operator evaluates its first sub-expression first, and then its second or third (never both of them) based on the value of the first.
  • Entry to and exit from a function call (but not between evaluations of the arguments).

Expressions before a sequence point are always evaluated before those after a sequence point. In the case of short-circuit evaluation, the second expression may not be evaluated depending on the result of the first expression. For example, in the expression (a() || b()), if the first argument evaluates to nonzero (true), the result of the entire expression will also be true, so b() is not evaluated.

[edit] Undefined behavior

An interesting (though certainly not unique) aspect of the C standard is that the behavior of certain code is said to be "undefined". In practice, this means that the program produced from this code can do anything, from working as intended, to crashing every time it is run.

For example, the following code produces undefined behavior, because the variable b is modified more than once with no intervening sequence point:

#include <stdio.h>

int main(void)
{
  int a, b = 1;
  a = b++ + b++;
  printf("%d\n", a);
  return 0;
}

Because there is no sequence point between the modifications of b in b++ + b++, it is possible to perform the evaluation steps in more than one order, resulting in an ambiguous statement. This can be fixed by rewriting the code to insert a sequence point:

a = b++;
a += b++;

[edit] See also

[edit] References

  • Kernighan, Brian W., and Dennis M. Ritchie. The C Programming Language. 2nd ed. Upper Saddle River, New Jersey: Prentice Hall PTR, 1988.

[edit] External links

In other languages
THIS WEB:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2006:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu