option to output variable @code{CC} to make it so. This macro tries
various options that select C99 on some system or another. It
considers the compiler to be in C99 mode if it handles @code{_Bool},
-flexible arrays, @code{inline}, @code{long long int}, mixed code and
-declarations, named initialization of structs, @code{restrict}, varargs
-macros, variable declarations in @code{for} loops and variable length
-arrays.
+@code{//} comments, flexible array members, @code{inline}, @code{long
+long int}, mixed code and declarations, named initialization of structs,
+@code{restrict}, @code{va_copy}, varargs macros, variable declarations
+in @code{for} loops, and variable length arrays.
After calling this macro you can check whether the C compiler has been
set to accept C99; if not, the shell variable
# If the C compiler is not in ISO C99 mode by default, try to add an
# option to output variable CC to make it so. This macro tries
# various options that select ISO C99 on some system or another. It
-# considers the compiler to be in ISO C99 mode if it handles mixed
-# code and declarations, _Bool, inline and restrict.
+# considers the compiler to be in ISO C99 mode if it handles _Bool,
+# // comments, flexible array members, inline, long long int, mixed
+# code and declarations, named initialization of structs, restrict,
+# va_copy, varargs macros, variable declarations in for loops and
+# variable length arrays.
AC_DEFUN([_AC_PROG_CC_C99],
[_AC_C_STD_TRY([c99],
[[#include <stdarg.h>
#include <wchar.h>
#include <stdio.h>
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
struct incomplete_array
{
int datasize;
typedef const char *ccp;
static inline int
-test_restrict(ccp restrict text)
+test_restrict (ccp restrict text)
{
// See if C++-style comments work.
// Iterate through items via the restricted pointer.
return 0;
}
-// Check varargs and va_copy work.
+// Check varargs and va_copy.
static void
-test_varargs(const char *format, ...)
+test_varargs (const char *format, ...)
{
va_list args;
- va_start(args, format);
+ va_start (args, format);
va_list args_copy;
- va_copy(args_copy, args);
+ va_copy (args_copy, args);
const char *str;
int number;
switch (*format++)
{
case 's': // string
- str = va_arg(args_copy, const char *);
+ str = va_arg (args_copy, const char *);
break;
case 'd': // int
- number = va_arg(args_copy, int);
+ number = va_arg (args_copy, int);
break;
case 'f': // float
- fnumber = (float) va_arg(args_copy, double);
+ fnumber = va_arg (args_copy, double);
break;
default:
break;
}
}
- va_end(args_copy);
- va_end(args);
+ va_end (args_copy);
+ va_end (args);
}
]],
[[
- // Check bool and long long datatypes.
+ // Check bool.
_Bool success = false;
- long long int bignum = -1234567890LL;
- unsigned long long int ubignum = 1234567890uLL;
// Check restrict.
- if (test_restrict("String literal") != 0)
+ if (test_restrict ("String literal") == 0)
success = true;
char *restrict newvar = "Another string";
// Check varargs.
- test_varargs("s, d' f .", "string", 65, 34.234);
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
- // Check incomplete arrays work.
+ // Check flexible array members.
struct incomplete_array *ia =
- malloc(sizeof(struct incomplete_array) + (sizeof(double) * 10));
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
ia->datasize = 10;
for (int i = 0; i < ia->datasize; ++i)
- ia->data[i] = (double) i * 1.234;
+ ia->data[i] = i * 1.234;
- // Check named initialisers.
+ // Check named initializers.
struct named_init ni = {
.number = 34,
.name = L"Test wide string",
ni.number = 58;
int dynamic_array[ni.number];
- dynamic_array[43] = 543;
+ dynamic_array[ni.number - 1] = 543;
// work around unused variable warnings
- return bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x';
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
]],
dnl Try
dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)