Я продолжаю задавать этот вопрос в интервью: Записать программу без использования функции main() ? Один из моих друзей показал мне код с использованием макросов, но я не мог этого понять. Итак, вопрос: Можно ли написать и скомпилировать программу без main() ?
Expert Novice 13 авг. 2011, в 16:44
Поделиться
Похоже, довольно глупый вопрос интервью . Может быть, вы забыли о некоторых деталях?
Gabriel Ščerbák 13 авг. 2011, в 14:20
Разве вы не любите эти практические вопросы интервью? /сарказм
Peter Alexander 13 авг. 2011, в 14:20
Как именно это показывает, может ли кандидат решить проблемы или вписаться? Достаточно сложно писать и поддерживать читаемые программы, зачем спрашивать о таких мерзостях? Если компания не называется IOCCC, то есть.
Omri Barel 13 авг. 2011, в 14:29
Это зависит от того, что они имеют в виду. Они имели в виду «без функции main ()»? или они имели в виду «Запускать код без запуска его из основного (даже косвенного)»?
Martin York 13 авг. 2011, в 16:10
Программирование на Си — Урок 6 — процедуры, функции, параметры и разгадка тайны int main
«Продолжай спрашивать»? Что, какой-то список под названием «TEH BESTEST C + Интервью Вопросы» только что был опубликован на веб-сайте? Где ты находишься? С кем ты беседуешь? Потому что я хочу бежать в другом направлении.
Я предполагаю, что если кто-то задаст вам этот вопрос, вы устраните их . И кстати, ответ «да», вы можете «написать и скомпилировать» такую программу, вы просто не можете успешно связать ее (по крайней мере, в стандартной, размещенной, совместимой системе). Я мог бы раскалывать волосы, но это был бы мой умный ответ, если бы мне задали вопрос.
Dan 13 авг. 2011, в 20:58
Показать ещё 3 комментария
Поделиться:
compilation
19 ответов
Лучший ответ
В стандартной функции С++ требуется функция main , поэтому вопрос не имеет смысла для стандартного С++.
Вне стандартного С++ вы можете, например, написать специальную программу Windows и использовать одну из функций запуска Microsoft (wMain, winMain, wWinmain). В Windows вы также можете написать программу как DLL и использовать rundll32 для ее запуска.
Кроме того, вы можете создать свою собственную небольшую библиотеку времени исполнения. Когда-то это был общий вид спорта.
Наконец, вы можете получить умные и возразить, что в соответствии со стандартным правилом ODR main не используется, поэтому любая программа подходит. Ба! Хотя, если у интервьюеров необычное хорошее чувство юмора (и они не задали бы вопрос, если бы у них было), они не подумают, что это хороший ответ.
Cheers and hth. — Alf 13 авг. 2011, в 15:55
Поделиться
Ой. Я планировал просто дать этот ответ B, с ошибкой для всех 2 C. (Хорошо, только что посмотрел фильм «Звездные войны»). Он был дополнен и исправлен, например , ответом Алса и ответом Йоханнеса Шауба . Теперь, если читатель причинно-следственной связи этого не увидит: автономная среда , например, такая как компилятор для DSP, позволяет использовать другие функции запуска, отличные от main .
argc argv c++ что это. Параметры функции main argc argv. Аргументы main. C ++ Урок #70
Cheers and hth. — Alf 13 авг. 2011, в 22:20
Cheers and hth. — Alf 14 авг. 2011, в 02:46
Я не анонимный downvoter — но я подозреваю, что это голосование против того, чтобы быть принятым ответом, когда это не точно. Это действительно плохой вопрос для интервью — но этот ответ вводит в заблуждение, поскольку он справедлив только для (по общему признанию, более распространенного) размещенного окружения.
iandotkelly 15 авг. 2011, в 00:56
Показать ещё 1 комментарий
Нет, вы не можете, если вы не пишете программу в freestanding environment (ядро операционной среды встроенной среды и т.д.), где отправной точкой не должно быть main() . Согласно стандарту С++ main() является отправной точкой любой программы в hosted environment .
В соответствии с:
С++ 03 стандарт 3.6.1 Основная функция
1 Программа должна содержать глобальную функцию main, которая является назначенным началом программы. Реализация определяется, требуется ли программа в автономной среде для определения основной функции. [Примечание: в автономной среде, запуск и окончание — это реализация; startup содержит выполнение конструкторов для объектов области пространства имен со статической продолжительностью хранения; завершение содержит выполнение деструкторов для объектов со статической продолжительностью хранения.
Что такое freestanding environment и что такое hosted environment ?
В стандарте С++ существует два типа совместимых реализаций; hosted и freestanding .
Реализация A freestanding — это программа, предназначенная для программ, которые выполняются без использования операционной системы.
Для Ex: Ядро ОС или встроенная среда будут автономной средой.
Программа, использующая средства операционной системы, обычно находится в hosted implementation .
Из С++ 03 Standard Раздел 1.4/7:
Внештатная реализация — это та, в которой выполнение может выполняться без использования операционной системы и имеет набор библиотек, поддерживающих реализацию, которые включают в себя определенные библиотеки поддержки языков.
Далее,
Раздел: 17.4.1.3.2. Кавычки, выполненные отдельно:
Внештатная реализация имеет набор заголовков, определенный реализацией. Этот набор должен включать по меньшей мере следующие заголовки, как показано в таблице:
18.1 Types 18.2 Implementation properties 18.3 Start and termination 18.4 Dynamic memory management 18.5 Type identification 18.6 Exception handling 18.7 Other runtime support
Alok Save 13 авг. 2011, в 16:04
Поделиться
Уверены ли вы?
Я имею в виду, что всем, кто пишет ядро ОС или встроенные программы, придется обходиться без основной функции, и я надеюсь, что такое не приведет к неопределенному поведению.
Voo 13 авг. 2011, в 14:54
Мне кажется странным, что сначала ты говоришь: «Нет, ты не можешь». но затем вы цитируете спецификацию, где говорится, что иногда вы можете опустить ее определение.
Johannes Schaub — litb 13 авг. 2011, в 14:55
Alok Save 13 авг. 2011, в 14:58
Alok Save 13 авг.
2011, в 15:03
Показать ещё 2 комментария
Пример программы без видимой основной функции.
/* 7050925.c $ gcc -o 7050925 7050925.c */ #include #define decode(s,t,u,m,p,e,d) m##s##u##t #define begin decode(a,n,i,m,a,t,e) int begin()
miku 13 авг. 2011, в 15:02
Поделиться
Чит. Я вижу главное 🙂
Martin York 13 авг. 2011, в 16:08
На самом деле, это так же хорошо, как #define begin() main() Вы можете просто добавить много менее известных / популярных конструкций C / C ++ и замаскировать их, но главное должно быть определено для реализации размещенной среды.
Добавление этого комментария здесь, потому что без этого ответ может быть немного вводит в заблуждение новичков.
Alok Save 13 авг. 2011, в 16:23
Этот код не без основного. gcc -E file.c даст вам код, который на самом деле компилируется.
phoxis 14 авг. 2011, в 04:03
Показать ещё 1 комментарий
main означает точку входа, точку, с которой ваш код начнет выполнение. хотя main не первая функция для запуска. Есть еще несколько кода, который выполняется до main и подготавливает среду для запуска вашего кода. Затем этот код вызывает main . Вы можете изменить имя функции main , перекомпилировав код загрузочного файла crt0.c и изменив имя функции main . Или вы можете сделать следующее:
#include extern void _exit (register int code); _start() < int retval; retval = my_main (); _exit(retval); >int my_main(void)
Скомпилируйте код с помощью
gcc -o no_main no_main.c -nostartfiles
-nostartfiles не будет включать файл запуска по умолчанию. Вы указываете основной файл записи с помощью _start .
main — не что иное, как предопределенная точка входа для кода пользователя. Поэтому вы можете это назвать, но в конце дня вам нужна точка входа. В языках C/С++ и других языках имя выбирается как main , если вы создаете другой язык или взламываете источники этих компиляторов языка, тогда вы можете изменить имя main на pain , но это принесет боль, поскольку оно будет нарушать стандарты.
Но манипулирование именем функции входа полезно для кода ядра, первой функции, запускаемой в ядре, или кода, написанного для встроенных систем.
phoxis 14 авг. 2011, в 05:52
Поделиться
Они могут ссылаться на программу, написанную для самостоятельной реализации. Стандарт С++ определяет два вида реализаций. Одна из них — хостинг. Программы, написанные для этих реализаций, должны иметь функцию main . Но в противном случае функция main не требуется, если автономная реализация не требует ее. Это полезно для ядер операционной системы или встроенных системных программ, которые не запускаются под операционной системой.
Johannes Schaub — litb 13 авг. 2011, в 15:28
Поделиться
Да, это возможно скомпилировать с основным, но вы не можете пройти фазу связи, хотя.
g++ -c noMain.cpp -o noMain.o
Mahesh 13 авг. 2011, в 15:02
Поделиться
Да
$ cat > hwa.S write = 0x04 exit = 0xfc .text _start: movl $1, %ebx lea str, %ecx movl $len, %edx movl $write, %eax int $0x80 xorl %ebx, %ebx movl $exit, %eax int $0x80 .data str: .ascii «Hello, world!n» len = . -str .globl _start $ as -o hwa.o hwa.S $ ld hwa.o $ ./a.out Hello, world!
Ядро, которое действительно запускает исполняемый файл, ничего не знает о внутренних символах, оно просто переносится в точку входа, указанную в двоичном виде в заголовке исполняемого файла.
Причина, по которой вам нужна основная, — это потому, что обычно ваша «основная программа» — это просто еще один модуль. Точка входа находится в коде запуска, предоставленном библиотекой, написанном в некоторой комбинации C и сборки, и этот код библиотеки просто вызывает вызов main , поэтому вам обычно необходимо его предоставить. Но запустите компоновщик напрямую, а вы этого не сделаете.
Чтобы включить модуль C 1 .
Mac:~/so$ cat > nomain.S .text .globl start start: call _notmain Mac:~/so$ as -o nomain.o nomain.S Mac:~/so$ cat > notmain.c #include void notmain(void) < write(1, «hin», 3); _exit(0); >Mac:~/so$ cc -c notmain.c Mac:~/so$ ld -w nomain.o notmain.o -lc Mac:~/so$ ./a.out hi
1. И я также переключаюсь на x86-64 здесь.
DigitalRoss 15 авг. 2011, в 00:54
Поделиться
«Без использования main » также может означать, что в пределах main не допускается никакая логика, но сама main существует. Я могу представить, что вопрос был устранен, но поскольку он не очищается здесь, это еще один возможный ответ:
struct MainSub < MainSub() < // do some stuff >>; MainSub mainSub; int main(int argc, char *argv[])
Что произойдет, так это то, что материал в конструкторе MainSub будет выполняться до выполнения неиспользуемого main , и вы можете поместить туда логику программы. Это, конечно, требует С++, а не C (также непонятно из вопроса).
eran 13 авг. 2011, в 17:02
Поделиться
Почему MainSub::MainSub() будет выполнен? Вы нигде не создаете объект MainSub?
Dan 13 авг. 2011, в 15:37
eran 13 авг.
2011, в 15:42
Ах да, я думал, что это будет просто декларация. Если бы это был примитив, то есть int , его значение было бы неопределенным, нет?
Dan 13 авг. 2011, в 15:45
eran 13 авг. 2011, в 15:55
Вы постоянно узнаете что-то новое о C ++. Я никогда не знал этого . хотя я должен был проверить это;) +1 за то, что научил меня чему-то новому.
Dan 13 авг. 2011, в 16:01
Показать ещё 3 комментария
Пока вы используете g++, вы можете изменить свою точку входа с помощью опции компоновщика -e , поэтому следующая команда кода и компиляции может позволить вам создать программу без функции main() :
#import class NoMain < public: NoMain() < std::cout > mainClass;
Я дал имя файла как noname.cpp , а параметр компиляции:
g++ nomain.cpp -Wl,-e,_mainClass -v
Честно говоря, я не совсем понял, почему код может работать нормально. Я подозреваю, что адрес глобальной переменной mainClass является тем же самым для конструктора класса NoMain . Тем не менее, у меня также есть несколько причин, по которым я могу сказать, что моя догадка не может исправить.
Joohae Kim 26 июль 2016, в 19:33
Поделиться
Я думаю, что ссылка на макрос была переименована в главную функцию, а не мой код и демонстрирует это. Компилятор все еще видит основную функцию, но технически там нет основной исходной точки зрения. Я получил его здесь http://www.exforsys.com/forum/c-and-c/96849-without-main-function-how-post412181.html#post412181
#include #define decode(s,t,u,m,p,e,d) m##s##u##t #define begin decode(a,n,i,m,a,t,e) int begin()
eon 13 авг. 2011, в 16:13
Поделиться
Я понимаю, что это старый вопрос, но я только что нашел это и должен был поделиться. Это, вероятно, не будет работать со всеми линкерами, но, по крайней мере, возможно обмануть ld (я запускаю версию 2.24.51.20140918), думая, что есть основная функция:
int main[] <>;
или даже просто
int main;
Затем вы можете применить один из вышеупомянутых трюков, чтобы программа могла выполнить некоторый код, например. с помощью конструктора:
struct Main < Main() < cout > main_;
exit(0) состоит в том, чтобы предотвратить «вызов» массива. Хорошая забава: -)
JorenHeit 28 окт. 2014, в 22:43
Поделиться
Без учета конкретных языковых стандартов большинство ссылочных загрузчиков предоставляют некоторые средства для объявления имени функции (точки входа), которое должно выполняться при загрузке двоичного файла, в память.
Для старого школьного языка c по умолчанию было что-то вроде «start» или «_start», определенное в так называемом crt (c runtime?), которое выполняет несколько домашних заданий, необходимых для стандартных функций c, таких как подготовка кучи памяти, инициализация статических областей переменных, разбор командной строки в argc/argv и т.д.
Возможно, вы можете переопределить функцию точки входа, если у вас достаточно внимания, чтобы не использовать стандартные функции, которые требуют этих домашних вещей (например, malloc(), free(), printf(), любые определения классов имеют пользовательский конструктор. ) Довольно ограничительный, но не невозможный, если вы используете функции, предоставляемые o/s, а не стандартными c runtime.
Например, вы можете создать простой helloworld, используя функцию write() в дескрипторе 1.
shr 13 авг. 2011, в 17:08
Поделиться
Когда выполняется код C или С++, он выполняется с известным начальным адресом, здесь здесь инициализирует среду выполнения, инициализирует указатель стека, выполняет инициализацию данных, вызывает статические конструкторы, а затем переходит к main().
Код, который делает это, связан с вашим кодом во время сборки компоновщиком. В GCC он обычно находится в crt0.s, с коммерческим компилятором маловероятно, что этот код будет доступен вам.
В конце концов, он должен начинаться где-то, а main() является просто символическим именем для этого местоположения. Он задается стандартом языка, чтобы разработчики знали, как его называть, иначе код не будет переносимым из одной цепочки инструментов в другую.
Если вы пишете код для «голого металла» без ОС или, по крайней мере, нет ОС в смысле загрузчика процессов (встроенные системы часто включают ядро RTOS, которое запускается после main()), тогда вы может теоретически называть точку ввода кода C тем, что вы хотите, поскольку обычно у вас есть полный контроль над кодом запуска во время выполнения. Но делать это было бы глупо и несколько порочным.
Некоторые среды RTOS, такие как VxWorks, и большинство инфраструктур приложений в целом включают main()) или его эквивалент) в пределах их собственного кода библиотеки, чтобы он выполнялся до кода пользовательского приложения. Например, приложения VxWorks начинаются с usrAppInit(), а приложения Win32 начинаются с WinMain().
Clifford 13 авг. 2011, в 16:42
Поделиться
1) Использование макроса, определяющего основные
#include #define fun main int fun(void)
2) Использование оператора привязки маркеров Вышеупомянутое решение имеет слово «главное» в нем. Если нам не разрешено даже писать основную информацию, мы используем оператор привязки маркеров (подробнее см. Это)
#include #define fun m##a##i##n int fun()
Источник: overcoder.net
Int main C: для чего нужна функция main, прототип в функции Cи
![]()
«Int main()» — это выражение, показыва ющее , что в программе присутствует главная функция main(), которая вернет в качестве значения целое число. В программе на С может быть несколько функций, но одна из них обязательно должна быть main(). Без нее программа не будет корректно работать, так как main() является управляющей и основной функцией.
main аргументы функции и командной строки
Все программы C++ должны иметь функцию main . При попытке скомпилировать программу C++ без main функции компилятор выдает ошибку. (Библиотеки и static библиотеки динамической main компоновки не имеют функции.) Функция main — это место, где начинается выполнение исходного кода, но перед тем, как программа войдет в функцию main , все static члены класса без явных инициализаторов задаются равным нулю. В Microsoft C++ глобальные static объекты также инициализируются перед записью в main . К функции применяются некоторые main ограничения, которые не применяются к другим функциям C++. Функция main :
- Не удается перегрузить (см. раздел Перегрузка функций).
- Не может быть объявлен как inline .
- Не может быть объявлен как static .
- Не может быть принято его адрес.
- Не удается вызвать из программы.
Сигнатура main функции
Функция main не имеет объявления, так как она встроена в язык. Если это так, синтаксис объявления для main будет выглядеть следующим образом:
int main(); int main(int argc, char *argv[]);
Если возвращаемое значение не указано в main , компилятор предоставляет возвращаемое значение, равное нулю.
Стандартные аргументы командной строки
Аргументы для main обеспечивают удобный анализ аргументов из командной строки. Типы для параметров argc и argv определяются языком. Имена argc и argv являются традиционными, но вы можете назвать их как угодно.
Используются следующие определения аргументов.
argc
Целое число, содержащее количество аргументов, следующих в argv. Параметр argc всегда больше или равен 1.
argv
Массив завершающихся null строк, представляющих введенные пользователем программы аргументы командной строки. По соглашению — это команда, argv[0] с помощью которой вызывается программа. argv[1] — первый аргумент командной строки. Последний аргумент из командной строки — argv[argc — 1] , и argv[argc] всегда имеет значение NULL.
Сведения о том, как отключить обработку из командной строки, см. в разделе Настройка обработки командной строки C++.
По соглашению argv[0] — это имя файла программы. Однако в Windows можно создать процесс с помощью CreateProcess . При использовании первого и второго аргументов ( lpApplicationName и lpCommandLine ), argv[0] возможно, не является именем исполняемого файла. Вы можете использовать для GetModuleFileName получения имени исполняемого файла и его полного пути.
Расширения, относящиеся к корпорации Майкрософт
В следующих разделах описывается поведение, зависят от майкрософт.
Функция wmain и _tmain макрос
Если вы разрабатываете исходный код для использования расширенных действий Юникода char, вы можете использовать точку входа, относяющуюся к Корпорации wmain Майкрософт, которая является версией для широкогоchar действия main . Ниже приведен действующий синтаксис объявления для wmain :
int wmain(); int wmain(int argc, wchar_t *argv[]);
Можно также использовать зависящий от _tmain Майкрософт макрос, который является макросом препроцессора, определенным в tchar.h . _tmain разрешается в , main если _UNICODE не задано значение . В противном случае функция _tmain разрешается в функцию wmain . Макрос _tmain и другие макросы, которые начинаются с _t , полезны для кода, который должен создавать отдельные версии как для узких, так и для широких charнаборов действий. Дополнительные сведения см. в разделе Использование сопоставлений универсального текста.
Возврат из void main
Как расширение Майкрософт функции main и wmain могут быть объявлены как возвращающие (без возвращаемого void значения). Это расширение также доступно в некоторых других компиляторах, но его использование не рекомендуется. Он доступен для симметрии, если main не возвращает значение.
Если вы объявите main или wmain как возвращающий void , вы не сможете вернуть exit код родительскому процессу или операционной системе с помощью инструкции return . Чтобы вернуть exit код, если main или wmain объявлен как void , необходимо использовать функцию exit .
Аргумент envp командной строки
Сигнатуры main или wmain позволяют дополнительному расширению майкрософт для доступа к переменным среды. Это расширение также распространено в других компиляторах для систем Windows и UNIX. Это традиционное имя envp , но параметру среды можно присвоить любое имя. Ниже приведены действующие объявления для списков аргументов, включающих параметр среды:
int main(int argc, char* argv[], char* envp[]); int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);
envp
Необязательный envp параметр представляет собой массив строк, представляющих переменные, заданные в среде пользователя. Этот массив завершается записью NULL. Его можно объявить как массив указателей на char () или как указатель на ( char char **envp ). char *envp[] Если программа использует wmain вместо main , используйте wchar_t тип данных вместо char .
Блок среды, передаваемый main в и wmain , является «замороженной» копией текущей среды. Если позже вы измените среду путем вызова putenv или _wputenv , текущая среда (возвращенная getenv или _wgetenv и _environ переменная или _wenviron ) изменится, но блок, на который envp указывает , не изменится. Дополнительные сведения о том, как отключить обработку среды, см. в разделе Настройка обработки командной строки C++. Аргумент envp совместим со стандартом C89, но не со стандартами C++.
Примеры аргументов для main
В следующем примере показано, как использовать argc аргументы , argv и envp для main :
// argument_definitions.cpp // compile with: /EHsc #include #include using namespace std; int main( int argc, char *argv[], char *envp[] ) < bool numberLines = false; // Default is no line numbers. // If /n is passed to the .exe, display numbered listing // of environment variables. if ( (argc == 2) _stricmp( argv[1], «/n» ) == 0 ) numberLines = true; // Walk through list of strings until a NULL is encountered. for ( int i = 0; envp[i] != NULL; ++i ) < if ( numberLines ) cout >
Анализ аргументов командной строки C++
Правила анализа командной строки, используемые кодом Microsoft C/C++, зависят от корпорации Майкрософт. Код запуска среды выполнения использует следующие правила при интерпретации аргументов, заданных в командной строке операционной системы:
- Аргументы разделяются пробелами (пробел или табуляция).
- Первый аргумент ( argv[0] ) обрабатывается особым образом. Он представляет имя программы. Это должен быть допустимый путь, поэтому разрешены части, заключенные в двойные кавычки ( » ). Эти знаки двойных кавычек не включаются в выходные данные argv[0] . Части, заключенные в двойные кавычки, предотвращают интерпретацию пробела или табуляции charв качестве конца аргумента. Последующие правила в этом списке не применяются.
- Строка, заключенная в двойные кавычки, интерпретируется как один аргумент, который может содержать charпробелы. Строку в кавычках можно встроить в аргумент. Курсор ( ^ ) не распознается как escape-действие charили разделитель. Внутри заключенной в кавычки строки пара двойных кавычек интерпретируется как одна экранированная двойная кавычка. Если командная строка заканчивается до того, как будет найдена закрывающая двойная кавычка, то в качестве последнего аргумента выводятся все charсчитанные до сих пор действия.
- Символ двойной кавычки после обратной косой черты ( » ) интерпретируется как литеральный символ двойной кавычки ( » ).
- Символы обратной косой черты считаются литералами, если сразу за ними не стоит двойная кавычка.
- Если двойная кавычка стоит после четного числа символов обратной косой черты, в массив argv помещается по одному символу обратной косой черты ( ) для каждой пары символов обратной косой черты ( \ ), а сама двойная кавычка ( » ) интерпретируется как разделитель строк.
- Если двойная кавычка стоит после нечетного числа символов обратной косой черты, в массив argv помещается по одному символу обратной косой черты ( ) для каждой пары символов обратной косой черты ( \ ). Двойная кавычка интерпретируется обратной косой чертой remaining как escape-последовательность, в результате чего литерал двойной кавычки ( » ) помещается в argv .
Пример анализа аргументов командной строки
В следующем примере программы показана передача аргументов командной строки:
// command_line_arguments.cpp // compile with: /EHsc #include using namespace std; int main( int argc, // Number of strings in array argv char *argv[], // Array of command-line argument strings char *envp[] ) // Array of environment variable strings < int count; // Display each command-line argument. cout
Результаты анализа командных строк
В следующей таблице показаны примеры входных данных и ожидаемые выходные данные, иллюстрирующие применение правил из приведенного выше списка.
| «abc» d e | abc | d | e |
| a\b d»e f»g h | a\b | de fg | h |
| a\»b c d | a»b | c | d |
| a\\»b c» d e | a\b c | d | e |
| a»b»» c d | ab» c d |
Развертывание подстановочных знаков
Компилятор Майкрософт при необходимости позволяет использовать подстановочные знакиchar, вопросительный знак ( ? ) и звездочку ( * ), чтобы указать аргументы имени файла и пути в командной строке.
Аргументы командной строки обрабатываются внутренней подпрограммой в коде запуска среды выполнения, которая по умолчанию не расширяет подстановочные знаки на отдельные строки в строковом массиве argv . Вы можете включить расширение с подстановочными знаками, включив setargv.obj файл ( wsetargv.obj файл для wmain ) в /link параметры компилятора или в командной строке LINK .
Дополнительные сведения о параметрах компоновщика для запуска среды выполнения см. в статье Параметры ссылок.
Настройка обработки из командной строки C++
Если программа не принимает аргументы командной строки, можно сохранить небольшой объем пространства, подавив подпрограмму обработки командной строки. Для этого включите файл noarg.obj (для main и wmain ) в параметры компилятора /link или командную строку LINK .
Аналогичным образом, если вы никогда не использовали таблицу среды для доступа к аргументу envp , можно подавить внутреннюю подпрограмму обработки среды. Для этого включите файл noenv.obj (для main и wmain ) в параметры компилятора /link или командную строку LINK .
Программа может вызывать семейство подпрограмм spawn или exec в библиотеке среды выполнения C. В этом случае не следует подавлять подпрограмму обработки среды, так как она используется для передачи данных о среде из родительского процесса в дочерний.
Источник: learn.microsoft.com