Может ли си программа не иметь функцию main да нет

Я продолжаю получать этот вопрос, заданный в интервью:

написать программу без использования ?

один из моих друзей показал мне код с помощью макросов, но я не мог его понять.

действительно ли можно написать и скомпилировать программу без main() ?

автор: Alok Save

20 ответов

в пределах СТАНДАРТНОГО C++ a main функция требуется, поэтому вопрос не имеет смысла для стандартного C++.

за пределами стандартного C++ вы можете, например, написать программу для Windows и использовать одну из пользовательских функций запуска Microsoft (wMain, winMain, wWinmain). В Windows вы также можете написать программу как DLL и использовать rundll32 для ее запуска.

кроме того, вы можете создать свою собственную небольшую библиотеку времени выполнения. Когда-то это было обычным делом. спорт.

наконец, вы можете получить умный и парировать, что в соответствии с правилом ODR стандарта main не «используется», поэтому любая программа квалифицируется. Ба! Хотя, если у интервьюеров нет необычного чувства юмора (а они бы не задали вопрос, если бы имели), они не подумают, что это хороший ответ.

int main или void main. int main vs void main c++. C ++ Для начинающих. Урок #71

автор: Cheers and hth. — Alf

нет, вы не можете, если вы не пишете программу в freestanding environment (embedded environment OS kernel etc.) где отправная точка не должна быть main() . Согласно стандарту C++ main() является отправной точкой любой программы в hosted environment .

стандарт C++03 основные функции 3.6.1

1 программа должна содержать глобальную функцию main, которая является назначенным началом программы. Это реализация-определяется, требуется ли программа в автономной среде для определения основной функции. [ Примечание: в автономной среде запуск и завершение определяется реализацией; запуск содержит выполнение конструкторов для объектов области пространства имен со статической продолжительностью хранения; завершение содержит выполнение деструкторов для объектов со статической продолжительностью хранения.

A freestanding реализация-это та, которая предназначена для программ, которые выполняются без использования операционной системы.
Например: ядро ОС или встроенная среда будут автономной средой.

программа, использующая средства операционной системы, обычно находится в hosted implementation .

от стандарт C++03 раздел 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

пример программы без видимого основная функция.

argc argv c++ что это. Параметры функции main argc argv. Аргументы main. C ++ Урок #70


/* 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

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

автор: phoxis

Они могут ссылаться на программу, написанную для автономной реализации. Стандарт C++ определяет два вида реализаций. Один hosted реализация. Программы, написанные для этих реализаций, должны иметь . Но в остальном-нет!—0—> функция необходима если freestanding вставка не требует одного. Это полезно для ядер операционной системы или встроенных системных программ, которые не выполняются в операционной системе.

автор: Johannes Schaub — litb

да, можно скомпилировать без main, но вы не можете пройти фазу связывания.

g++ -c noMain.cpp -o noMain.o
автор: Mahesh

Да

$ cat > hwa.S write = 0x04 exit = 0xfc .text _start: movl , %ebx lea str, %ecx movl $len, %edx movl $write, %eax int x80 xorl %ebx, %ebx movl $exit, %eax int x80 .data str: .ascii «Hello, world!n» len = . -str .globl _start $ as -o hwa.o hwa.S $ ld hwa.o $ ./a.out Hello, world!

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

причина, по которой вам нужен main, заключается в том, что обычно ваша «основная программа» — это просто еще один модуль. Точка входа находится в предоставленном библиотекой коде запуска, написанном в некоторой комбинации 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

«без использования main » может также означать, что в main , а существует. Я могу представить, что вопрос был очищен, но поскольку он не очищен здесь, это еще один возможный ответ:

struct MainSub < MainSub() < // do some stuff >>; MainSub mainSub; int main(int argc, char *argv[])

что здесь произойдет, так это то, что материал в MainSub конструктор будет выполняться перед неиспользуемым main выполняется, и вы можете разместить логике программы там. Это, конечно, требует C++, а не C (также не ясно из вопрос.)

автор: eran

Я думаю, что ссылка на макрос была переименована в основную функцию, ниже не мой код, и демонстрирует это. Компилятор по-прежнему видит основную функцию, но технически нет основной с точки зрения источника. Она у меня здесь.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()

пока вы используете g++ , вы можете изменить точку входа с помощью опции компоновщика -e , поэтому следующая команда кода и компиляции может позволить вам создать программу без :

#import class NoMain < public: NoMain() < std::cout > mainClass;

Я дал имя файла как noname.cpp , и опция компиляции:

g++ nomain.cpp -Wl,-e,_mainClass -v

по правде говоря, я не совсем понял, почему код может работать нормально. Я подозреваю, что адрес глобальной переменной mainClass — это же конструктор NoMain класса. Однако Я также есть несколько причин, по которым я могу сказать, что моя догадка может быть неправильной.

автор: Joohae Kim

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

для языка старой школы c по умолчанию было что-то вроде «start» или «_start», определенное в так называемой crt (C runtime?), который выполняет несколько домашних заданий, необходимых для стандартных функций c, таких как подготовка кучи памяти, инициализация областей статических переменных, разбор командной строки на АГДС/агду и т. д.

возможно, вы могли бы переопределить функцию точки входа, если вы достаточно осторожны, чтобы не использовать стандартные функции, которые требуют этих бытовых вещей (например, malloc (), free (), printf (), любые определения классов имеют пользовательский конструктор. ) Довольно ограничительный, но не невозможный, если вы используете функции, предоставляемые o/s, а не стандартной средой выполнения C.

например, вы можете сделать простой helloworld, используя функцию write () в дескрипторе 1.

когда выполняется код C или C++, он выполняется по известному стартовому адресу, код здесь инициализирует среду выполнения, инициализирует указатель стека, выполняет инициализацию данных, вызывает статические конструкторы,затем переход к main().

код, который делает это, связан с вашим кодом во время сборки компоновщиком. В GCC он обычно находится в crt0.s, с коммерческим компилятором маловероятно, что этот код будет доступен вам.

В конце концов, он имеет для начала где-нибудь и main() — Это просто символическое название для этого места. Он определяется стандартом языка, чтобы разработчики знали, как его называть, иначе код не будет переноситься из одной цепочки инструментов в другую.

Читайте также:
Как установить программу принтера на ноутбук без диска

Если вы пишете код для системы «голого металла» без ОС или, по крайней мере, без ОС в смысле загрузчика процессов (встроенные системы часто включают ядро RTOS, которое запускается после main ()), то теоретически вы можете вызвать запись кода C укажите все, что вы хотите, так как у вас обычно есть полный контроль над кодом запуска во время выполнения. Но делать это было бы глупо и несколько извращенно.

некоторые среды RTOS, такие как VxWorks, и большинство фреймворков приложений в целом включают main() )или его эквивалент в свой собственный код библиотеки, чтобы он выполнялся перед кодом приложения пользователя. Например, приложения VxWorks начинаются с usrAppInit (), а приложения Win32-с WinMain ().

автор: Clifford

Я понимаю, что это старый вопрос, но я только что узнал и решил поделиться с ней. Это, вероятно, не будет работать со всеми компоновщиками, но, по крайней мере, можно обмануть ld (я запускаю версию 2.24.51.20140918) в мышление, что есть основной -функции при этом:

int main[] <>;

или даже просто

int main;

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

struct Main < Main() < cout > main_;

на exit(0) для предотвращения «вызова»массива. Весело 🙂

автор: JorenHeit

возможно, можно скомпилировать a .раздел данных и заполнить его кодом?

автор: Bytemain

Это зависит от того, что они означают.

Они имели в виду:

написать программу без функции main ().

тогда вообще нет.
Но есть способы обмануть.

  • вы можете использовать предварительный процессор, чтобы скрыть main () на виду.
  • большинство компиляторов позволяют определить точку входа в код.
    По умолчанию это main (int,char*[])

или они имею в виду:

напишите программу, которая запускает код без использования main (для запуска кода).

Это относительно простой трюк. Все объекты в глобальном пространстве имен запускают свои конструкторы до ввода main() и уничтожения после выхода main (). Таким образом, все, что вам нужно сделать, это определить класс с конструктором, который запускает нужный код, а затем создать объект в глобальном пространстве имен.

Примечание: компилятору разрешено оптимизировать эти объекты для отложенная загрузка (но обычно нет), но для безопасности просто поместите global в тот же файл, что и основная функция (которая может быть пустой).

автор: Martin York

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

автор: Dawid Królak

напишите класс и напечатайте свое имя в конструкторе этого класса и объявите глобальный объект этого класса. Таким образом, конструктор класса выполняется перед main. Таким образом, вы можете оставить основное пустое и по-прежнему печатать свое имя.

class MyClass < myClass() < cout >; MyClass gObj; // this will trigger the constructor. int main() < // nothing here. >
автор: John Gummadi

1) Использование макроса, определяющего main

#include #define fun main int fun(void)

2) Использование Оператора Вставки Токенов В приведенном выше решении есть слово «main». Если нам не дают даже написать, можно использовать оператор вставки токена (см. подробности)

#include #define fun m##a##i##n int fun()
автор: anshuman singh

да можно написать программу без функции main().

но он использует main() косвенно.

следующая программа поможет вам понять..

#include #define decode(s,t,u,m,p,e,d) m##s##u##t #define begin decode(a,n,i,m,a,r,e) int begin()

оператор «# # » называется оператором вставки маркеров или слияния маркеров. То есть мы можем объединить с ним два или более символов.

во 2-й строке программы —

определить декодирование (s,t,u,m,p,e, d) m##s##u##t

что здесь делает препроцессор. Этот декодирование макросов (s,t,u,m,p,e,d) расширяется как «msut» (оператор ## объединяет m,s,u begin» декодированием расширения(a,n,i,m,a,r,e). Согласно определению макроса в предыдущей строке, аргумент должен быть расширен так,чтобы 4-й, 1-й, 3-й и 2-й символы должны быть объединены. В аргументе (a,n,i,m,a,r,e) 4-й,1-й, 3-й и 2-й символы — «m», «a», » i » и «n».

таким образом, он заменит begin на main() препроцессором перед передачей программы для компилятора. Вот оно.

автор: Saraswati Katakdhond

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

#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()

здесь main написана макро-трюками. Это может быть не ясно сразу, но в конечном итоге это приводит к main. Если это правильный ответ на ваш вопрос, это можно сделать очень легко, вот так.

# include # define m main int m()

Источник: askdev.ru

Ответы: Аттестационный курс_Итоговый тест по Программированию 1/2 (80% правильно)

Отметьте утверждение, несправедливое для текстовых файлов:

При открытии файла для записи могут быть выполнены следующие действия:

При открытии файла для дополнения могут быть выполнены следующие действия:

При открытии файла для дополнения могут быть выполнены следующие действия:

Текстовые файлы хранят данные во ___ представлении

При открытии файла для чтения могут быть выполнены следующие действия:

Если при открытии файла для чтения функция feof() возвращает значение истина, то .

При закрытии файла могут быть выполнены следующие действия:

Отметьте виды файлов в Си:

Объем памяти, занимаемый структурой, равен:

Какие термины обозначают сложную структуру данных?

Отметьте операции, являющиеся операциями выбора компоненты структурированной переменной:

Отметьте свойства, неправильные для структур:

Структуры в программировании нужны для .

Допустима ли инструкция: s=»text», если s описано так: char s[6]?

В языке Си константа ‘а’ занимает . байтов памяти.

В языке Си константа «а» занимает . байтов памяти.

Строковый литерал «1234567890» занимает . байтов памяти.

Допустима ли инструкция: char *s=»text»?

Сколько байтов памяти занимает переменная str, объявленная с помощью инструкции: char str[]»слово»?

Верно ли утверждение: «В Си для объявление файловой переменной используется тип FILE*»?

Отметьте утверждения, справедливы для глобальных переменных:

Справедливо ли утверждение: «каждый файл Си-программы содержит ровно одну функцию»?

Отметьте утверждения, справедливые для локальных данных:

Локальные переменные при распределении в памяти .

Директива #define М 10:

К статическим данным не относятся:

Отметьте утверждения, справедливые для статических данных:

Глобальные переменные при распределении в памяти:

Директива #include препроцессора позволяет .

Назначение препроцессора Си состоит в .

Справедливо ли утверждение: «если функция большая, она может быть распределена по нескольким файлам»?

Справедливо ли утверждение:»каждый файл Си программы обязательно содержит хотя бы одну функцию»?

Если а -одномерный массив. i целая переменная. то выражение формальные параметры функции Си заменяются на фактические только по значению»?

Отметьте правильные свойства функции Си:

Отметьте правильные свойства формальных параметров функции Си:

Подпрограммы нужны для .

Функция типа void .

Стек функций -это .

В Си все подпрограммы являются функциями?

Отметьте правильные свойства фактических параметров функции Си

Действия, которые не осуществляет функция fopen():

В текстовом файле F содержится одна строка: «text file», переменная s описана так: char s[100]; Отметьте значение s после выполнения оператора:

В результате вычисления выражения А-В/С, если А, В и С объявлены как целые и А=О 8=5 С=2 будет получено значение .

Что делает оператор присваивания?

Описания данных в программе это .

Для массивов справедливы утверждения:

Свойства, включаемые в определение алгоритма:

Что делает оператор ввода?

Может ли Си-программа не иметь функцию main?

Основные алгоритмические структуры:

Тип данных характеризует …

Блок, имеющий более одного выхода:

Операторы программы -это .

Источник: studizba.com

Можно ли написать программу без использования функции main ()?

Один из моих друзей показал мне код с использованием макросов, но я не смог его понять.

Таким образом, вопрос заключается в том,

Можно ли написать и скомпилировать программу без main() ?

Expert Novice 13 Авг 2011 в 18:11
Кажется, довольно глупый вопрос для интервью . Может, вы забыли о какой-то детали?
Gabriel Ščerbák
13 Авг 2011 в 18:20
Разве вам не нравятся эти практические вопросы на собеседовании? /сарказм
Peter Alexander

13 Авг 2011 в 18:20

Как именно это показывает, может ли кандидат решать проблемы или соответствовать? Достаточно сложно писать и поддерживать читабельные программы, зачем спрашивать о таких мерзостях? Если только компания не называется IOCCC.

Читайте также:
Программа обновления до вин 11

Omri Barel
13 Авг 2011 в 18:29

Все зависит от того, что они имеют в виду. Они имели в виду «без функции main ()»? или они имели в виду «Запускать код, не запуская его из основного (даже косвенно)»?

Martin York
13 Авг 2011 в 20:10

«Продолжайте спрашивать»? Что, какой-то список под названием «САМЫЕ ЛУЧШИЕ вопросы на собеседовании C +» только что был размещен в Интернете? Где вы находитесь? С кем вы проводите собеседование? Потому что я хочу убежать в другую сторону.

Я предлагаю, чтобы если кто-то задает вам этот вопрос, вы удалите их . И, кстати, ответ — «да», вы можете «написать и скомпилировать» такую ​​программу, но вы просто не можете успешно связать ее (по крайней мере, в стандартной, размещенной, совместимой системе). Может, я и раскалываюсь, но это был бы мой умный ответ, если бы мне задали этот вопрос.

14 Авг 2011 в 00:58

21 ответ

Лучший ответ

В стандартном C ++ требуется функция main , поэтому вопрос не имеет смысла для стандартного C ++.

Помимо стандартного C ++, вы можете, например, написать программу для Windows и использовать одну из пользовательских функций запуска Microsoft (wMain, winMain, wWinmain). В Windows вы также можете написать программу как DLL и использовать rundll32 для ее запуска.

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

Наконец, вы можете быть умным и возразить, что согласно стандартному правилу ODR main не «используется», поэтому любая программа подходит. Ба! Хотя, если у интервьюеров нет необычного хорошего чувства юмора (а они бы не задавали этот вопрос, если бы у них было), они не подумают, что это хороший ответ.

Lightness Races in Orbit 14 Июн 2016 в 22:58
Cheers and hth. — Alf
14 Авг 2011 в 02:20

Голосующий против: объясните, почему вы проголосовали против, чтобы другие могли извлечь выгоду из вашего мнения.

Cheers and hth. — Alf
14 Авг 2011 в 06:46

Я не анонимный голосующий против, но я подозреваю, что это голосование против того, чтобы это был принятый ответ, хотя он не является точным. Это действительно плохой вопрос для собеседования, но этот ответ вводит в заблуждение, поскольку он верен только для (по общему признанию, более распространенной) размещенной среды.

iandotkelly
15 Авг 2011 в 04:56

Нет, нельзя, если вы не пишете программу на freestanding environment (ядро встроенной среды ОС и т. Д.), Где отправной точкой не обязательно будет main() . Согласно стандарту C ++ main() является отправной точкой любой программы в hosted environment .

В соответствии с:

Стандарт C ++ 03 3.6.1 Основная функция

1 Программа должна содержать глобальную функцию с именем main, которая является назначенным запуском программы. Это определяется реализацией, требуется ли программа в автономной среде для определения основной функции. [Примечание: в автономной среде запуск и завершение определяются реализацией; запуск содержит выполнение конструкторов для объектов области пространства имен со статической продолжительностью хранения; завершение содержит выполнение деструкторов для объектов со статической продолжительностью хранения.

Что такое freestanding Environment и что такое Hosted Environment ?
В стандарте C ++ определены два типа соответствующих реализаций; hosted и freestanding .

Реализация freestanding предназначена для программ, которые выполняются без использования операционной системы.
Например: ядро ​​ОС или встроенная среда будут автономной средой.

Программа, использующая возможности операционной системы, обычно находится в hosted implementation .

Из стандарта C ++ 03 Раздел 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
asthasr 5 Май 2016 в 17:31

Вы уверены? Я имею в виду, что всем, кто пишет ядро ​​ОС или встроенные программы, придется обходиться без основной функции, и я надеюсь, что это не приведет к неопределенному поведению.

13 Авг 2011 в 18:54

Мне кажется странным, что сначала вы говорите: «Нет, не можете». но затем вы цитируете спецификацию, в которой говорится, что иногда вы можете опустить ее определение.

Johannes Schaub — litb
13 Авг 2011 в 18:55
13 Авг 2011 в 18:58
13 Авг 2011 в 19:03

Пример программы без visible основной функции.

/* 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 в 18:29

На самом деле this ничем не хуже #define begin() main() . Вы можете просто добавить много менее известных / Popular конструкции C / C ++ и замаскируйте его, но основной должен быть определен для реализации размещенной среды, добавив этот комментарий здесь, потому что без этого ответ может немного ввести в заблуждение новичков.

13 Авг 2011 в 20:23
Этот код не лишен main. gcc -E file.c предоставит вам код, который фактически компилируется.
14 Авг 2011 в 08:03

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 / C ++ и других языках имя выбрано как main , если вы создаете другой язык или взламываете исходные коды этих языковых компиляторов, вы можете изменить имя main на pain , но это принесет боль, так как нарушит стандарты.

Но манипулирование именем входной функции полезно для кода ядра, первой функции, запускаемой в ядре, или кода, написанного для встроенных систем.

phoxis 14 Авг 2011 в 08:47

Они могут относиться к программе, написанной для автономной реализации. Стандарт C ++ определяет два вида реализаций. Один из них — размещенная реализация. Программы, написанные для этих реализаций, должны иметь функцию main . Но в противном случае функция main не требуется, если она не требуется для автономной реализации. Это полезно для ядер операционных систем или встроенных системных программ, которые не работают под управлением операционной системы.

Johannes Schaub — litb 13 Авг 2011 в 18:50

Да, можно скомпилировать без main, но вы не можете пройти фазу компоновки.

g++ -c noMain.cpp -o noMain.o
Mahesh 13 Авг 2011 в 18:14

«Без использования main » также может означать, что внутри main не допускается никакой логики, но сам main существует. Я могу представить, что вопрос был прояснен, но, поскольку здесь он не очищен, это еще один возможный ответ:

struct MainSub < MainSub() < // do some stuff >>; MainSub mainSub; int main(int argc, char *argv[])

Здесь произойдет то, что содержимое конструктора MainSub будет выполнено до того, как будет выполнен неиспользуемый main , и вы сможете поместить туда логику программы. Это, конечно, требует C ++, а не C (также не ясно из вопроса).

eran 13 Авг 2011 в 19:20
Зачем казнить MainSub::MainSub() ? Вы нигде не создаете объект MainSub?
13 Авг 2011 в 19:37
13 Авг 2011 в 19:42

Да ладно, я думал, это будет просто декларация. Если бы это был примитив, то есть int , его значение не было бы определено, не так ли?

Читайте также:
Какие произведения читают в 8 классе по литературе по программе

13 Авг 2011 в 19:45
13 Авг 2011 в 19:55

Вы все время узнаете что-то новое о C ++. Я никогда не знал этого . хотя мне пришлось это проверить;) +1 за то, что научил меня чему-то новому.

13 Авг 2011 в 20:01

Пока вы используете 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 в 22:09

Я думаю, что ссылка на макрос заключалась в переименовании основной функции, это не мой код, который демонстрирует это. Однако компилятор по-прежнему видит главную функцию, но технически с точки зрения исходного кода main не существует. Я нашел здесь 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()
user481572 13 Авг 2011 в 18:20

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

Для старого школьного языка c по умолчанию было что-то вроде ‘start’ или ‘_start’, определенное в так называемом crt (c runtime?), Который выполняет несколько домашних заданий, необходимых для стандартных функций c, таких как подготовка кучи памяти, инициализация статической переменной областей, парсинг командной строки в argc / argv и т. д.

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

Например, вы можете создать простой helloworld, используя функцию write () для дескриптора 1.

shr 13 Авг 2011 в 19:17

Когда код C или C ++ выполняется, он выполняется с известным начальным адресом, код здесь инициализирует среду выполнения, инициализирует указатель стека, выполняет инициализацию данных, вызывает статические конструкторы, затем переходит к main ( ).

Код, который делает это, связывается с вашим кодом во время сборки компоновщиком. В GCC он обычно находится в crt0.s, с коммерческим компилятором маловероятно, что этот код будет вам доступен.

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

Если вы пишете код для «голой» системы без ОС или, по крайней мере, без ОС в смысле загрузчика процессов (встроенные системы часто включают ядро ​​RTOS, которое запускается после main () ), то теоретически вы можете вызывать точку входа кода C как хотите, поскольку обычно вы полностью контролируете код запуска во время выполнения. Но поступить так было бы глупо и несколько порочно.

Некоторые среды RTOS, такие как VxWorks, и большинство фреймворков приложений в целом включают main ()) или его эквивалент) в код собственной библиотеки, чтобы он выполнялся перед кодом пользовательского приложения. Например, приложения VxWorks запускаются с usrAppInit (), а приложения Win32 запускаются с WinMain ().

Clifford 19 Авг 2011 в 23:27

Напишите класс и напечатайте свое имя в конструкторе этого класса и объявите ГЛОБАЛЬНЫЙ ОБЪЕКТ этого класса. Таким образом, конструктор класса выполняется перед main. Таким образом, вы можете оставить главное пустым и по-прежнему печатать свое имя.

class MyClass < myClass() < cout >; MyClass gObj; // this will trigger the constructor. int main() < // nothing here. >
John Gummadi 19 Дек 2012 в 21:53

Я понимаю, что это старый вопрос, но я только что узнал об этом и должен был поделиться. Вероятно, это не будет работать со всеми компоновщиками, но, по крайней мере, можно обмануть ld (я использую версию 2.24.51.20140918), заставив думать, что есть функция main- , сделав следующее:

int main[] <>;

Или даже просто

int main;

Затем вы можете применить один из вышеупомянутых приемов, чтобы позволить программе выполнить некоторый код, например с помощью конструктора:

struct Main < Main() < cout > main_;

exit(0) предотвращает «вызов» массива. Хорошо повеселиться 🙂

JorenHeit 29 Окт 2014 в 15:49

Да, вы можете сделать это, изменив точку входа языка C с main () на _start Вот код:

#include #include int sid()

Затем запустите код с помощью gcc complier. Предположим, вы сохранили файл с именем test.c.

gcc -nostartfiles test.c ./a.out
CreatorGhost 21 Янв 2021 в 10:31

Может, можно скомпилировать секцию .data и заполнить ее кодом?

Micromega 13 Авг 2011 в 18:15

Все зависит от того, что они имеют в виду.

Они имели в виду:

Напишите программу без функции main ().

Тогда вообще нет.
Но есть способы обмануть.

  • Вы можете использовать препроцессор, чтобы скрыть main () на виду.
  • Большинство компиляторов позволяют указать точку входа в код.
    По умолчанию это main (int, char * [])

Или они имели в виду:

Напишите программу, которая запускает код без использования main (для запуска вашего кода).

Это относительно простой прием. Все объекты в глобальном пространстве имен запускают свои конструкторы до входа в main () и уничтожение после выхода из main (). Таким образом, все, что вам нужно сделать, это определить класс с конструктором, который запускает нужный вам код, а затем создать объект в глобальном пространстве имен.

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

Martin York 13 Авг 2011 в 20:19

Функция main — это только метка по умолчанию для адреса, с которого программа начнет выполнение. Так что технически да, это возможно, но вы должны указать имя функции, которая начнет выполнение в вашей среде.

Dawid Królak 14 Авг 2011 в 02:26

1) Использование макроса, определяющего основной

#include #define fun main int fun(void)

2) Использование оператора вставки токена. В приведенном выше решении есть слово «main». Если нам не разрешено даже писать main, мы можем использовать оператор вставки токена (подробности см. Здесь)

#include #define fun m##a##i##n int fun()
Anshuman Singh 9 Сен 2014 в 19:26

Да, можно написать программу без main ().

Но он использует main () косвенно.

Следующая программа поможет вам понять ..

#include #define decode(s,t,u,m,p,e,d) m##s##u##t #define begin decode(a,n,i,m,a,r,e) int begin()

Оператор «##» называется оператором вставки или объединения токенов. То есть мы можем объединить с ним двух или более персонажей.

Во 2 строке программы —

Определить decode (s, t, u, m, p, e, d) m ## s ## u ## t

Что здесь делает препроцессор. Макро-декодирование (s, t, u, m, p, e, d) раскрывается как «msut» (оператор ## объединяет m, s, u private: // public: printMe()< coutprotected: // >obj; int main()<>
crispengari 1 Июн 2020 в 19:38

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

#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()

Здесь main написано макросами. Это может быть не сразу понятно, но в конечном итоге приводит к main. Если это правильный ответ на ваш вопрос, это можно сделать очень легко, например так.

# include # define m main int m()

Источник: question-it.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru