// filename:c2011-6-7-3-1-ex.c
// original examples and/or notes:
// 		(c) ISO/IEC JTC1 SC22 WG14 N1570, April 12, 2011
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
// 			C2011 6.7.3.1 Formal definition of restrict
// compile and output mechanism:
// 		(c) Ogawa Kiyoshi, kaizen@gifu-u.ac.jp, December.xx, 2013
// compile errors and/or wornings:
// 1	(c) Apple LLVM version 4.2 (clang-425.0.27) (based on LLVM 3.2svn)
// 			Target: x86_64-apple-darwin11.4.2 //Thread model: posix
// 		(c) LLVM 2003-2009 University of Illinois at Urbana-Champaign.
// 2    gcc-4.9 (GCC) 4.9.0 20131229 (experimental)
//      Copyright (C) 2013 Free Software Foundation, Inc.
#define C2011_6_7_3_1_EX
// compile cc c2011-6-7-3-1-ex.c c2011-ex.c 
#include "c2011-ex.h"
#include <stdio.h>
// Example 2	
void f(int n, int * restrict p, int * restrict q)
{
while (n-- > 0)
*p++ = *q++;
}
void g(void)
{
extern int d[100];
f(50, d + 50, d); // valid
f(50, d + 1, d); // undefined behavior
}
// Example 3
void h(int n, int * restrict p, int * restrict q, int * restrict r)
{
int i;
for (i = 0; i < n; i++)
p[i] = q[i] + r[i];
}
// Example 4
void i(void)
	{
int * restrict p1;
int * restrict q1;
p1 = q1; // undefined behavior
{
int * restrict p2 = p1; // valid
int * restrict q2 = q1; // valid
p1 = q2; // undefined behavior
p2 = q2; // undefined behavior
}
}
typedef struct { int n; float * restrict v; } vector;
vector new_vector(int n)
{
vector t;
t.n = n;
t.v = malloc(n * sizeof (float));
return t;
}

int main(void)
{
	
// Example 1
int * restrict a;
int * restrict b;
extern int c[];
	f(c[0],a,b);
return printf("6.7.3.1 Formal definition of restrict %d %d %d\n",a,b,c[0]);	
}
// 1. output LLVM3.2 may be
// 6.7.3.1 Formal definition of restrict 1787153048 0 0
// 2. output GCC4.9
// 6.7.3.1 Formal definition of restrict 1792262238 1545435856 0