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.
func3 expects a non const type and promises not to change it via the const keyword preceding the type in the argument list. The others are fine with taking pointers to const types since CTVPtr is a pointer to const data.

I think the confusion came from the const key word you used which actually meant func3 will not change the data pointed by p rather than saying func3 will accept a const TVPtr.

If you really want to pass address of i to func3, you can cast it like this

```
func3( (void*)&i);

```