Question: Suppose we have two structs

```
struct hello {  
  float a;
  float b;
};

```

and

```
struct world {
  float c;
  float d;
};

```

and a function

```
void func(struct hello* h, struct world* w);

```

Is it the case that the two arguments can alias, as they both contain `float` and therefore the compiler must generate a code that ensures correctness? If I am certain that `w` and `h` are not stored in the same memory location (or do not overlap in any way), would I achieve speed-up by changing the function to the following?

```
void func(struct hello *restrict h, struct world *restrict w);

```

Moreover, does the primitive type of `float` have any effect on this or do the same rules apply to an `int`?

Answer: 
Your example is very close to creating two structs that are of *compatible type* (C11 6.2.7). But in order to be compatible, they must have the same members with the same names, and the struct tags must also be the same. 

You don't have that, so (TL;DR) the structs in the question cannot alias.

Another thing one can play around with however, is a trick called *common initial sequence* (C11 6.5.2.3) where you can put both structs inside a union, which is visible in the translation unit. You'd then be allowed to inspect the first sequence of members of each struct type, until the point where they stop being compatible. You could do this:

```
typedef union
{
  struct hello h;
  struct world w;
} hack_t;

```

Then access individual members of either struct. Unfortunately, this rule is a bit exotic and compilers don't always support it well apparently - the rule was subject to some Defect Reports (DR). I'm not certain of its status in current C17.

But regardless of that trick, the union still makes it possible to lvalue access a `struct hello` or a `struct world` through a `hack_t`, since it is a union type that includes a compatible type among its members (C11 6.5/7). Mildly useful I suppose.

Apart from those cases, you cannot wildly cast pointer types from one pointer type to the other and de-reference. It would be a strict aliasing violation (C11 6.5/7) even if all individual members are compatible types. (You can however of course access any individual `float` member by de-referencing a `float` pointer to that member.)

Your `restrict` optimization does not apply since the structs can't alias, unless they are truly compatible types. So the compiler will assume they are always in different memory regions.

It doesn't matter if you use `float` or any other primitive data type, they all behave the same with the exception of the character types. A pointer to a character type can be used to access any data without strict aliasing violation (but not the other way around, reading character type through another incompatible type).
> 
> If I am certain that w and h are not stored in the same memory location (or do not overlap in any way), would I achieve speed-up by changing the function to the following?
> 
> 
> 
> ```
> void func(struct hello *restrict h, struct world *restrict w);
> 
> ```
> 
> 

My understanding of the C11 standard (read [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)) is that some implementations (in practice some optimizing compilers, when asked to optimize enough, e.g. a *recent* [GCC](https://gcc.gnu.org/) invoked as `gcc -O3`) *could* achieve speed-up thanks to the `restrict` keyword.

But that speedup might be *very* small. And it might be related to [undefined behavior](http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html).

At last, your example is a common case where usual practice and programmer expectations and the C standard could diverge. Consider using static source analysis tools such as [Frama-C](https://frama-c.com/) or [Clang static](https://clang-analyzer.llvm.org/) analyzers (or switch to a better language, perhaps [Rust](https://www.rust-lang.org/)).