// c2011-6-7--2-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.2.1 Structure and union specifiers
// compile and output mechanism
// (c) Ogawa Kiyoshi, kaizen@gifu-u.ac.jp, December.xx, 2013
// compile errors and/or warnings:
// 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.
#include <stdio.h>
#include <stdlib.h> 
#include <stddef.h>

int main(void)
{
// Example 1
struct v {
union { // anonymous union
struct { int i, j; }; // anonymous structure
struct { long k, l; } w;
};
int m;
} v1;

v1.i = 2; // valid
//	v1.k = 3; // invalid: inner structure is not anonymous
//	c2011-6-7-2-1-ex.c:24:4: error: no member named 'k' in 'struct v'
//v1.k = 3; // invalid: inner structure is not anonymous
//~~ ^
v1.w.k = 5; // valid

struct s { int n; double d[]; };

int m = /* some value */ 0;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

struct s t1 = { 0 }; // valid
//struct s t2 = { 1, { 4.2 }}; // invalid
//c2011-6-7-2-1-ex.c:37:20: error: initialization of flexible array member is not allowed
//struct s t2 = { 1, { 4.2 }}; // invalid
//                   ^

t1.n = 4; // valid
t1.d[0] = 4.2; // might be undefined behavior

if(sizeof (struct s) >= offsetof(struct s, d) + sizeof (double)) printf("s ");

struct ss { int n; };

if(sizeof (struct s) >= sizeof (struct ss)) printf("ss ");
if(sizeof (struct s) >= offsetof(struct s, d)) printf("ssd ");
struct s *s1;
struct s *s2;
s1 = malloc(sizeof (struct s) + 64);
s2 = malloc(sizeof (struct s) + 46);

struct { int n; double d[8]; } *ss1;
struct { int n; double d[5]; } *ss2;
ss1 = malloc(sizeof (struct s) + 10);
ss2 = malloc(sizeof (struct s) + 6);

	struct { int n; double d[1]; } *s21, *s22;
	s21 = malloc(sizeof (struct s) + 1);
s22 = malloc(sizeof (struct s) + 1);
	s21->d[0]=1.1;
	s22->d[0]=1.1;
double *dp;
dp = &(s21->d[0]); // valid
*dp = 42; // valid
dp = &(s22->d[0]); // valid
*dp = 42; // undefined behavior
*s21 = *s22;
// EXAMPLE 3 
struct ss3 {
struct { int i; };
int a[];
	}*ss4;
	ss4 =   malloc(sizeof (struct ss3) );
	return printf("6.7.2.1 Structure and union specifiers %d %d %d %d %d %d %d %d %d %d %f\n",v1.i,t1.n, p->n,s22->n,s1->n,s2->n,s21->n, ss1->n, ss2->n,ss4->a[0],*dp);
}
// 1.output  LLVM3.2 may be
// Segmentation fault: 11
// 2. output GCC4.9
// ss ssd 6.7.2.1 Structure and union specifiers 5 4 0 0 0 0 0 0 0 0 42.000000