Ответ 1
Существует разница между константным указателем и указателем на константу. Константный указатель - это указатель (номер - адрес памяти), который не может быть изменен - он всегда указывает на тот же объект, данный через инициализацию:
int * const const_pointer = &some_int_var; // will be always pointing to this var
const_pointer = &some_other_var; // illegal - cannot change the pointer
*const_pointer = 2; // legal, the pointer is a pointer to non-const
Указатель на константу - это указатель, чье остроконечное значение не может быть изменено:
const int * pointer_to_const = &some_int_var; // doesn't have to be always pointing to this var
pointer = &some_other_var; // legal, it not a constant pointer and we can change it
*pointer = 2; // illegal, pointed value cannot be changed
Вы всегда можете назначить константу переменной i.e. const указателю на указатель не-const (a). Вы можете указывать указатель на не-const указатель на const (b). Но вы не можете наложить указатель на const на указатель на неконстантный (c):
int * pointer;
int * const const_pointer = &var;
const int * pointer_to_const;
/* a */
pointer = const_pointer; // OK, no cast (same type)
/* b */
pointer_to_const = pointer; // OK, casting 'int*' to 'const int*'
/* c */
pointer = pointer_to_const; // Illegal, casting 'const int*' to 'int*'
[EDIT] Ниже, это не стандартный С++. Однако это обычное явление. [/EDIT]
Строковый литерал
"Hello"
преобразуется в константный указатель на const (const char * const
):
char *pointer = "Hello"; // Illegal, cannot cast 'const char*' to 'char*'
char * const const_pointer = "Hello"; // Illegal, cannot cast 'const char*' to 'char*'
const char * pointer_to_const = "Hello"; // OK, we can assign a constant to a variable of the same type (and the type is 'const char*')
"Hello" = pointer_to_const; // Illegal cannot re-assign a constant
В приведенных выше примерах второе - ваше дело. Вы пытались инициализировать указатель на не-const с помощью указателя на константу при передаче строкового литерала в качестве аргумента вашей функции. Независимо от того, являются ли эти указатели константами или нет, важно, на что они указывают.
Резюме:
1) Если вы указали какой-либо указатель на какой-либо указатель другого типа, вы не можете использовать pointer-to-const для указателя на не-const.
2) Если у вас есть постоянный указатель, применяются те же правила, что и для других констант - вы можете назначить константу переменной, но вы не можете назначить переменную константе (кроме ее инициализации).
//EDIT
Как отметил GMan, стандарт С++ 98 (§4.2/2) позволяет неявно лить строковые литералы (которые являются постоянными массивами char) указателю не const char. Это связано с обратной совместимостью (на языке C нет констант).
Конечно, такое преобразование может привести к ошибкам, и компиляторы нарушат правило и покажут ошибку. Однако GCC в режиме совместимости показывает только предупреждение.