Ответ 1
Вверх по С++ 03, ваш первый пример был действительным, но использовал устаревшее неявное преобразование - строковый литерал должен рассматриваться как имеющий тип char const *
, так как вы не можете изменять его содержимое (не вызывая undefined).
Начиная с С++ 11, неявное преобразование, которое было устаревшим, было официально удалено, поэтому код, который зависит от него (например, ваш первый пример), больше не должен компилироваться.
Вы отметили один способ разрешить компиляцию кода: хотя неявное преобразование было удалено, явное преобразование все еще работает, поэтому вы можете добавить листинг. Однако я бы не подумал об этом "исправлении" кода.
Истинное исправление кода требует изменения типа указателя на правильный тип:
char const *p = "abc"; // valid and safe in either C or C++.
Что касается того, почему это было разрешено на С++ (и все еще находится в C): просто потому, что существует много существующего кода, который зависит от этого неявного преобразования, и нарушение этого кода (по крайней мере, без какого-либо официального предупреждения), по-видимому, казалось стандартные комитеты, как плохая идея.