В чем отличие cstdio от stdio.h
Вероятно заголовок моего вопроса звучит глупо. Но, у меня вопрос следующего рода: в данном видео (27:15-27:50) человек решает задачу и говорит, что большая часть времени занимает сугубо ввод и вывод. А далее вместо #include <cstdio> пишет #include <stdio.h>, и меняет тип выводимой переменной с %lld на %I64 и это ускоряет программу аж в 2 раза. Почему данные действия ускорили программу?
Ссылка на задачу из видео: https://acmp.ru/asp/do/index.asp?main=topic&id_course=2&id_section=20&id_topic=46
Ответы (1 шт):
Программу компилировали MinGW. Он может использовать две разные реализации printf:
- от майкрософта
- свою самодельную (дальше буду называть ее "ANSI")
Похоже, что первый вариант быстрее. Но он не умеет как минимум в %lld (поэтому на видео используют нестандартный %I64d) - поэтому и сделали альтернативную версию.
Экспериментально выяснил, что выбор между ними происходит так:
| Язык | Хедер | Вариант |
|---|---|---|
| C | <stdio.h> |
-std=c90 и старее -> MS-std=c99 и новее -> ANSI |
| C++ | <stdio.h> |
-std=c++98 -> MS-std=c++11 и новее -> ANSI |
| C++ | <cstdio> |
всегда ANSI |
Проверял на MSYS2. Без явного указания стандарта, у меня всегда выбирался ANSI - потому что дефолтный стандарт достаточно новый.
Можно переопределить выбор варианта, используя -D__USE_MINGW_ANSI_STDIO=0 и 1 (MS и ANSI соответственно), или #define __USE_MINGW_ANSI_STDIO 0 и 1 (до инклудов).
Проверить, какой вариант используется, можно #if __USE_MINGW_ANSI_STDIO == 1.
Поскольку дефолтное значение зависит от стандарта, выбирать его через разные варианты хедера (как на видео) - выглядит ненадежно. Если для вас это важно, лучше явно задавать __USE_MINGW_ANSI_STDIO.
Если интересно, то логика, угадывающая дефолтное значение, тут:
/* We are activating __USE_MINGW_ANSI_STDIO for various define indicators.
* printf ll modifier (unsupported by msvcrt.dll) is required by C99 and C++11 standards. */
#if (defined (_POSIX) || defined (_POSIX_SOURCE) || defined (_POSIX_C_SOURCE) \
|| defined (_ISOC99_SOURCE) \
|| (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && __MSVCRT_VERSION__ < 0xE00) \
|| (defined (__cplusplus) && __cplusplus >= 201103L && __MSVCRT_VERSION__ < 0xE00) \
|| defined (_XOPEN_SOURCE) || defined (_XOPEN_SOURCE_EXTENDED) \
|| defined (_GNU_SOURCE) \
|| defined (_SVID_SOURCE)) \
&& !defined(__USE_MINGW_ANSI_STDIO)
/* Enable __USE_MINGW_ANSI_STDIO if user did _not_ specify it explicitly... */
# define __USE_MINGW_ANSI_STDIO 1
#endif