Значение ios_base:: sync_with_stdio (false); cin.tie(NULL);

Каково значение включения

ios_base::sync_with_stdio(false);
cin.tie(NULL);

в программах C++?

В моих тестах это ускоряет время выполнения, но есть ли контрольный пример, о котором мне следует беспокоиться, если включить это?

Всегда ли два оператора должны быть вместе или достаточно первого, то есть игнорировать cin.tie(NULL)?

Также допустимо ли использовать одновременные команды C и C++, если его значение было установлено в false?

https://www.codechef.com/viewsolution/7316085

Приведенный выше код работал нормально, пока я не использовал scanf/printf в программе C++ со значением true. В этом случае это дало ошибку сегментации. Что может быть возможным объяснением этого?

Ответ 1

Два вызова имеют разные значения, которые не имеют никакого отношения к производительности; тот факт, что он ускоряет время выполнения, является (или может быть) просто побочным эффектом. Вы должны понимать, что каждый из них делает, а не слепо включать в каждую программу, потому что они выглядят как оптимизация.

ios_base::sync_with_stdio(false);

Это отключает синхронизацию между стандартными потоками C и С++. По умолчанию все стандартные потоки синхронизированы, что на практике позволяет вам смешивать ввод-вывод типа C и С++ и получать разумные и ожидаемые результаты. Если вы отключите синхронизацию, то потокам С++ разрешено иметь свои собственные независимые буферы, что делает смешение ввода-вывода типа C и С++ приложением.

Также имейте в виду, что синхронизированные потоки С++ являются потокобезопасными (вывод из разных потоков может чередоваться, но вы не получаете расов данных).

cin.tie(NULL);

Это отделяет cin от cout. Связанные потоки обеспечивают, чтобы один поток сбрасывался автоматически перед каждой операцией ввода-вывода в другом потоке.

По умолчанию cin привязан к cout для обеспечения разумного взаимодействия с пользователем. Например:

std::cout << "Enter name:";
std::cin >> name;

Если привязаны cin и cout, вы можете ожидать, что вывод будет сброшен (т.е. видимый на консоли), прежде чем программа предложит ввести пользователя. Если вы развяжете потоки, программа может заблокировать ожидание ввода пользователем своего имени, но сообщение "Ввести имя" еще не видно (поскольку cout буферизовано по умолчанию, вывод сбрасывается/отображается на консоли только по требованию или когда буфер заполнен).

Итак, если вы развяжете cin с cout, вы должны обязательно очищать cout вручную каждый раз, когда хотите отобразить что-либо перед ожиданием ввода на cin.

В заключение, знайте, что каждый из них делает, понимают последствия, а затем решают, действительно ли вы хотите или нуждаетесь в возможном побочном эффекте повышения скорости.

Ответ 2

Это для синхронизации ввода-вывода из мира C и C++. Если вы синхронизируете, то у вас есть гарантия, что порядок всех операций ввода-вывода - это именно то, что вы ожидаете. В общем, проблема заключается в буферизации операций ввода-вывода, которая вызывает проблему, синхронизация позволяет обоим мирам использовать одни и те же буферы. Например, cout << "Hello"; printf("World"); cout << "Ciao";; без синхронизации вы никогда не узнаете, получите ли вы HelloCiaoWorld или HelloWorldCiao или WorldHelloCiao...

tie дает вам гарантию того, что каналы ввода-вывода в мире C++ связаны друг с другом, что означает, например, что каждый выход был очищен до того, как произойдет ввод (подумайте о cout << "What your name ?"; cin >> name;).

Вы всегда можете смешивать C или C++ IO, но если вы хотите разумного поведения, вы должны синхронизировать оба мира. Помните, что в общем случае не рекомендуется смешивать их, если вы программируете на C, используете C stdio, и если вы программируете на C++, используйте потоки. Но вы можете захотеть смешать существующие библиотеки C с кодом C++, и в этом случае необходимо синхронизировать оба.

Ответ 3

Использование ios_base::sync_with_stdio(false); достаточно для разделения потоков C и C++. Вы можете найти обсуждение этого в Стандартных C++ IOStreams и Locales Лангера и Крефта. Они отмечают, что то, как это работает, определяется реализацией.

Кажется, что вызов cin.tie(NULL) запрашивает разделение между действиями в cin и cout. Я не могу объяснить, почему использование этого с другой оптимизацией может вызвать сбой. Как уже отмечалось, ссылка, которую вы предоставили, является плохой, поэтому здесь нет спекуляций.