1

В ряде вопросов на ruSO, например, здесь, а также в вопросах на CyberForum (например, вот), да и в целом на просторах интернета многие люди сталкиваются с проблемой, описанной в заголовке вопроса. Как исправить её, я знаю из тех же вопросов. Почему возникает, тоже в курсе. Вопрос в другом – почему не возникает у меня?

Если подробнее: попытался для решения вопроса по первой ссылке воспроизвести проблему, чтобы проверить своё решение, а потом уже написать его в ответ. И столкнулся с тем, что у меня прекрасно и без каких-либо проблем работает то, что вызывает вопросы у других. Например, такой простой код:

#include <iostream>

int main() { char * x = "Hello"; std::cout << x << std::endl;

getchar();
return 0;

}

компилируется без проблем и, как и ожидалось, выводит "Hello" как на VS 2015, так и на VS 2008.

Ещё раз вопрос: почему у меня не воспроизводится описанная выше проблема и const char * без проблем присваивается char *? Каковы условия возникновения данной ошибки?

user7860670
  • 29,796
V-Mor
  • 5,127
  • Вероятно, потому что у вас не очень свежая студия? =) – vp_arth Dec 08 '20 at 04:37
  • По указанной вами же ссылке на киберфорум расписано, что сталкиваются с проблемой в более свежих версиях студии, которые работают по более свежим стандартам С++. И там же расписано, как с этой конкретной ошибкой бороться (несколькими способами, от приведения типов, до настройки компилятора). – SelfishCrawler Dec 08 '20 at 04:38
  • @vp_arth, возможно. На 19ой потестить пока руки не дошли. Но неужто с новыми стандартами настолько кардинально пересмотрели взгляды на подобные присвоения? Как говорит kleshenki, не в студии дело. – V-Mor Dec 08 '20 at 04:38
  • @kleshenki, как бороться я понимаю. Я не пойму, почему мне не приходится этого делать ни на одной из студий. – V-Mor Dec 08 '20 at 04:40
  • Ну как же не в студии, дело в стандарте) И это не ошибка, а diagnostic message – vp_arth Dec 08 '20 at 04:43
  • Потому что 2015 студия это откровенно говоря немного старовато уже, а 2008 я вообще молчу) И сделано это по всей видимости не чтобы костылей наставить разработчикам, а для защиты от неверных обращений к памяти. К тому же, новому компилятору, насколько я знаю, можно явно указать более старый стандарт для работы. – SelfishCrawler Dec 08 '20 at 04:43
  • @vp_arth, Тогда не могли бы Вы рассказать в ответе, как работало данное присвоение раньше и как работает в современных стандартах? И в каком стандарте произошёл "роковой перелом"? – V-Mor Dec 08 '20 at 04:45

1 Answers1

3

Эта проблема существовала давно. Однако версии Visual Studio до 2013 реализовали нестандартное поведение и разрешали навалидную инициализацию указателя без const квалификатора строковым литералом. Затем они приняли курс на соответствие стандартам и в Visual Studio 2013 появилась возможность включаить конформное поведение посредством аргумента /Zc:strictStrings. А начиная с Visual Studio 2017 появился режим общего соответствия стандартам /permissive-, который теперь используется по-умолчанию при создании новых проектов.

Кроме того, был исправлен еще один случай не конформного поведения - попытка напрямую инициализировать bool строковым литералом bool foo{"foo"}; теперь корректно распознается как ошибка.

user7860670
  • 29,796
  • Ещё Visual Studio может указатель на функцию неявно преобразовать в void*, хотя по стандарту такие финты можно проделывать только через reinterpret_cast. Но это тоже можно исправить какими-то ключами (какими именно сходу не скажу)). – Джонни Кэтсвилл Dec 08 '20 at 11:48
  • @ДжонниКэтсвилл по стандарту такого преобразования раньше вообще не допускалось, а сейчас вроде как отдается на откуп реализации. – user7860670 Dec 08 '20 at 12:58