C99 features in GCC on Fedora

The New C

C99 is the C standard ratified by the ANSI and ISO standardizaion groups. It presents a significant amount of changes to the C language. These changes are the result of sibling competition between C and C++. The initial version of C is named after Kernighan and Ritchie. Classic C is K&R C with structure assignment, enumerations, and void. C89, or ANSI C, had some influences from C with Classes. For example, C89 adopted function prototypes in a similar form to what C with Classes provided. The most significant changes in C99, compared to C89, support a variety of new features.

Following is a brief list of C99 features:

  • Boolean data types <stdbool.h>
  • Increased identifier size limits
  • C++ style/line comments
  • Inline functions
  • Restricted pointers
  • Variable Declarations
  • Variable length arrays
  • New long long type

Specific standards

The new C standard for gcc is applied with the following command.

$gcc -Wall -std=c99 filename.c

Let us consider the following program named bool.c:

/*bool.c */
#include <stdio.h>
#include <stdbool.h>
int main(int argc, char *argv[])
{
  bool b = true;
  if(b)
    printf("It is a true Boolean data type supported only in C99\n");
  else
   printf("Boolean data type is not supported in C99\n");
  return 0;
}

$ gcc -Wall -std=c99  bool.c
$ ./a.out
It is a true Boolean data type supported only in C99

Linking C99 programs with external libraries

The C standard library consists of a collection of headers and library routines used by C programs. The external library is usually stored with an extension .a and known as a static library. For instance, the C math library is typically stored in the file /usr/lib/libm.a on Linux. The prototype declarations for the functions in the math library are specified in the header file /usr/include/math.h.

/*hypotenuse.c*/
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[])
{
  float x,y,h;
  //C99 program to demonstrate the use of external math library function
  printf("\n Enter the values for x and y\n");
  scanf("%f %f", &x,&y);
  h=hypotf(x,y);
  printf(" The Hypotenuse of x and y is %f\n", h);
  return 0;
}

Consider the above program hypotenuse.c. The following commands are then executed:

$ gcc -Wall -std=c99 hypotenuse.c /usr/lib/libm.so -o hypt
$ ./hypt
Enter the values for x and y
6.0
8.0
The Hypotenuse of x and y is 10.000000

gcc provides an -l option to override long paths when linking against libraries. The following command illustrates this option:

$ gcc -Wall -std=c99  hypotenuse.c -lm -o hypt
$ ./hypt
Enter the values for x and y
4.0 8.0
The Hypotenuse of x and y is 8.944272

Mixed declarations

ISO C99 allows declarations and code to simultaneously exist in compound statements. The following programming example illustrates this feature:

/*mixednewdec.c*/
#include<stdio.h>
int main(int argc, char*argv[])
{
  for(int i=2; i>0 ; --i)
  {
    printf("%d", i);
    int j = i * 2;
    printf("\n %d \n", j);
  }
}

$ gcc -Wall -std=c99  mixednewdec.c
$ ./a.out
2
4
1
2

The identifier is visible from where it is declared to the end of the enclosing block.

Variable Length Arrays(VLA)

Variable Length Arrays are not dynamic arrays. Rather, they are created with different sizes each time a declaration is encountered. Only local arrays which are within block scope can be variable arrays.

/*vla.c*/
#include<stdio.h>
int main(int argc, char *argv[])
{
  int j = 10;
  void func(int);
  func(j);
  return 0;
}

void func(int x)
{
  int arr[x];
  for(int i=1; i<=x; i++)
  {
    int j=2;
    arr[i] = j*i;
    printf("%d\n",arr[i]);
  }
}

Previously array sizes were of fixed size. C99 removes this constraint. It also frees you from performing allocate( ) and delete( ) operations on memory explicitly. The output of VLA is illustrated below.

$ gcc -Wall -std=c99 vla.c
$ ./a.out
2
4
6
8
10
12
14
16
18
20

New Long Long Type

Long long is 64 bit wide integer type. This is the biggest integer type in the C language standard. The long long type was specified to give 32-bit machines a way to handle 64-bit data when interactingwith 64 bit machines. Consider the following C program longdt.c:

/*longdt.c*/
#include <stdio.h>
int main(int argc, char *argv[])
{
  long long num1 = 123456789101LL;
  long int num2 = 12345678;
  printf("Size of %lld is %u bytes\n", num1 ,sizeof(num1));
  printf("Size of %ld is %u bytes\n", num2 ,sizeof(num2));
  return 0;
}

$ gcc -Wall -std=c99 longdt.c
$ ./a.out
Size of 123456789101 is 8 bytes
Size of 12345678 is 4 bytes

Restricted Pointers

C99 lets you prefix pointer declarations with the restrict keyword. Thus the pointer itself will be used to access the object it points to. This features takes care of the shortfall of aliasing. It also aids in code optimization. For example, consider the signature of strcat() function in the string.h file:

char *strcat (char* restrict dest,  const char * src)

The source string is appended to the end of the destination string. Here, the destination and source strings can be referenced only through the pointers dest and src. The compiler can then optimize the code generated for the function.

Inline Functions

Inline functions save the overhead of function calls. Consider the following program inlinecode.c to demonstrate the use of inline in C99.

/*myheader.h*/

#ifndef MYHEADER_H
#define MYHEADER_H

inline int min(int a, int b)
{
  return a < b ? a : b;
}

#endif

/*inlinecode.c*/

#include <stdio.h>
#include "myheader.h"
extern int min(int,int);
int main(int argc, char *argv[])
{
  int a =10, b=20;
  int min_value = min(10,20);
  printf(" The minimum of a and b is %d\n", min_value);
  return 0;
}

$ gcc -Wall -std = c99 inlinecode.c
$ ./a.out
The minimum of a and b is 10

Conclusion

C99 is a step ahead in the evolution of ANSI C. It incorporates elegant features like single line comments, boolean data types and larger size data types. C99 also supports code optimization through restricted pointer usage and supports inline functions. Now programmers can exploit these new features and further optimize their code for programming efficiency.

For Developers

10 Comments

  1. Frederik

    C99 has been supported by GCC for ages. The standard setting for GCC was elevated to C99 some years ago (don’t recall exactly when). The -new- standard for C is called C11 and has been available since 2011.

    The current default C dialect in the current GCC in Fedora is gnu11, meaning C11 with some extensions.

    • Gary

      A quick Google search and a wiki read seems to confirm your comment. C99 was released in 1999(big shocker there), while the current standard C11 was released in, again big surprise, 2011.

    • Gary

      A quick Google search and a wiki read seems to confirm your comment. C99 was released in 1999(big shocker there), while the current standard C11 was released in, again big surprise, 2011. So not sure what the article is about.

  2. David Novák

    “New C” 😀

    Author is mere 17 years behind… If he wrote about C11, it would still be kinda funny, but acceptable… Writing about C99 (which has been default in GCC for long time) is like “eh.. what?”

  3. Smittty

    Almost nothing mentioned in this article is actually explained in enough detail to be informative, classic example is the inline function example. There is zero examination (proof might be a better word) of how the use of inline essentially eliminates the overhead of a function call.

    So, not only is this article 17 years too late, but even if it had been produced in 1999, it would be largely uninformative.

    My suspicion is that this article was little more than a school assignment so that an H1-B candidate could have something on their resume proving they could speak English and understood basic C programming.

    So, nothing to see here, move along.

    • bobbel42

      Not only is nothing really explained, but there are actually bugs in the examples. Take the variable length array example for instance: when you define an array with length N you can access the elements of the array with index 0 through (N – 1), not 1 through N as in the example.

      Did provide me with a reason to lookup the ‘-fbounds_check’, ‘-fsanitize=bounds’ and ‘-fsanitize=bounds_strict’ options to gcc though 😉

      (turns out -fbounds_check only works for Java and Fortran and both the -fsanitize= options catch the bug in the example (and it also thought me the difference between variable length arrays and flexible array members))

  4. icywind

    Is it supposed to be some kind of a joke?

  5. Irakli

    afaik MS Visual Studio still only supports c89 for its C compiler…
    but article is informative for beginers and non-C programmers

  6. As many readers pointed out, C99 is not new. The article seeks to explain some known changes in C99, but not to make a case that these features are contemporary when there are newer standards. We hope to have some other articles on newer standards and features for developers that are helpful to show how tools have changed over time. Contributions are welcome!

  7. Thanks for the candid and insightful comments.

    C99 has found utilization in writing cryptography algorithms .

    Cryptography library TinyECC can be implemented in devices other than TinyOS -dependent devices as the library can be ported to C99 through manual alteration of code parts .

    SAFEcrypto Secure Architectures of Future Emerging Cryptography in its approved software requirements specification document dated 22 April 2016 mentions that the main
    codebase is written in ANSI C99 (ISO/IEC 9899:1999). They further mention that the software
    suite can be targeted for both resource -constrained embedded platforms and high performance multi-core architectures. The software is mainly written in performance-optimized C99 language.

    OpenCL is an open, royalty-free standard for general purpose parallel programming across
    CPUs. The OpenCL C Specification Version:2.0 Document Revision: 33 updated on April 13, 2016 says that, The OpenCL C programming language (also referred to as OpenCL C) is based on the ISO/IEC 9899:1999 C language specification (a.k.a. C99 specification) with specific extensions and restrictions.

    C99 provides better support for Floating point exceptions.

    Thus from cryptography algorithms to parallel programming to getting support from Microsoft to Apple -iOS, C99 is making headway and this article is a small delta contribution in that direction.

Comments are Closed

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions