Question: ```
    typedef void* TVPtr;
    typedef const void* CTVPtr;

const TVPtr func3 (const TVPtr p)
{
    return p;
}

const void* func4 (const void* p)
{
    return p;
}

CTVPtr func5 (CTVPtr p)
{
    return p;
}

int main ()
{
    const uint64_t i = 10;

    func3(&i);  // compilation error here
                // cannot convert argument 1 from 'const uint64_t *' 
                // to 'const TVPtr' Conversion loses qualifiers    
    func4(&i);  // no compilation error
    func5(&i);  // no compilation error
    return 0;

}

```

I do not understand why there is error is one case and not in the other two?

Answer: 
```
const TVPtr

```

means:

```
void * const  //correct

```

**not** this:

```
const void*   //wrong

```

which you seems to think.

---

### Visualization has power to influence your understanding.

This is one reason why I believe putting `const` after the type is a better practice. So if you have this practice:

```
void const * x;

```

instead of

```
const void * x; //same as void const *x!

```

then it helps with typedef and template.

For example, take this typedef:

```
typedef void* voidptr;

```

Now if you write the following and try to visualize what it is:

```
voidptr const x;

```

then you're more likely to visualize it as:

```
void* const x; //correct

```

which is in fact what it is.

With `const` before the type is counter-intuitive:

```
const voidptr x;

```

seems to be:

```
const void* x; //wrong

```

which is actually wrong — it is still this:

```
 void* const x; //correct

```

So putting `const` after the type helps visualizing the final type.
`const TVPtr` is not `const void*`, it's `void* const`. In other words, it's not a pointer to `const void`, it's a `const` pointer to `void`. Since `i` is declared `const` it will happily bind to a `const void*`, but not a `void* const`, because that discards the `const`ness of the object itself.