Каково происхождение основной пустоты? - программирование

Каково происхождение основной пустоты?

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

Почему я все еще вижу, как новые люди забирают плохую привычку, когда main ничего не возвращает, когда правильным способом является возвращение int. Я понимаю, почему этот метод неверен, как объясняется в этом вопросе и множестве других, но я не понимаю, как появился этот метод объявления main или даже почему все еще преподается некоторым студентам.

4b9b3361

Ответ 1

Даже Bjarne Stroustrup написал void main, в С++, так что это действительно общий анти-мем и старый, предшествующий Java и другим современным языкам, поддерживающим void main. Конечно, Bjarne также написал, что void main никогда не был частью C или С++. Однако для этого последнего утверждения (в его FAQ), по крайней мере, с C99, похоже, что Бьярн ошибается, потому что черновик N869 стандарта C99 говорит в его §5.1.2.2.3/1, что

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

И ранее, в своем п .5.1.2.2.1/1 он заявляет о сигнатуре main,

"или каким-либо другим способом реализации."

Тип возврата, "несовместимый с int", может быть, например, void.

Итак, хотя это не полный ответ (я сомневаюсь, что исторические источники об этом доступны в сети), по крайней мере, он имеет какое-то отношение к исправлению предположений вопроса. Это не тот случай, когда void main является полной мерзостью в C и С++. Но в С++ он недействителен: это вещь C, которая не поддерживается в размещенной реализации С++.

Ответ 2

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

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

Следовательно, это приводит к неправильной привычке использовать void main() из самой первой лекции нашего C-программирования.

Надеюсь, что это хорошо объясняет, почему большинство программистов, особенно новых, берут эту плохую практику.

Cheers, Майанк

Ответ 3

Лично я считаю, что следующее: K & RC не требовал указать тип возврата и неявно предполагал, что он является int, и в то же время примеры из K & R не используйте возвращаемое значение.

Например, первый код в первом издании K & R следующий:

#include <stdio.h>

main() 

{
   printf("Hello World\n");
}

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

На самом деле K & R скажет позже:

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

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

Ответ 4

Как один из авторов среди других, Герберт Шильдт написал несколько популярных, но не обязательно высококачественных книг, которые поддержали идею.

Одним из вопиющих примеров является его "Аннотированный стандарт C" . Он цитирует стандарт ISO/IEC 9899: 1990 на левых страницах и предоставляет аннотации на правых страницах. Когда он цитирует раздел 5.1.2.2.1 "Запуск программы", он говорит:

Функция, вызванная при запуске программы, называется main. Реализация не объявляет прототипа для этой функции. Он может быть определен без параметров:

int main(void) { /* ... */ }

или с двумя параметрами (...):

int main(int argc, char *argv[]) { /* ... */ }

Это не включает предложение "или в какой-то другой реализации, определенный образом", которое было добавлено на C99.

Затем в аннотации он говорит:

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

void main(void)  /* no return value, no parameters */

int main(void)   /* return a value, no parameters */

/* return a value and include command-line parameters */
int main(int argc, char *argv[])

Первая вариация не допускается стандартом C90, несмотря на то, что он говорит, но невинные читатели могут быть смущены.

Обратите внимание, что раздел 5.1.2.2.3 Окончание программы говорит:

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

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

В комментарии говорится:

В большинстве реализаций возвращаемое значение из main(), если оно есть, возвращается операционной системе. Помните, что если вы явно не возвращаете значение из main(), тогда значение, переданное операционной системе, технически равно undefined. Хотя большинство компиляторов автоматически возвращают 0, если не указано другое возвращаемое значение (даже если main() объявлен как void), вы не должны полагаться на этот факт, потому что он не гарантируется стандартом.

Некоторые из этих комментариев - это так много экскрементов крупного рогатого скота, представление, в котором я не одинок в удержании. Единственное достоинство книги состоит в том, что она включает почти весь стандарт C90 (там одна страница отсутствует в описании fprintf - одна и та же страница дважды печатается) гораздо меньше, чем стоимость стандарта. Утверждалось, что разница в цене представляет собой потерю ценности из комментария. См. Lysator в целом для некоторой информации о C и Обзор Clive Feather Стандарта аннотированного C.

Еще одна из его книг - C: полная ссылка, которая сделала это, по крайней мере, в 4-м выпуске. 3rd Edition использовал void main() экстенсивно; это, возможно, было очищено 4-м изданием, но было грустно, что потребовалось много выпусков, чтобы получить такую ​​фундаментальную проблему.

Ответ 5

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

Ответ 6

Возможные причины:

  • Java-программисты использовали для записи public static void main(...).
  • Недопустимый оператор return может предположить, что main не возвращается, хотя он неявно возвращает 0.
  • В C вы могли написать main() без возвращаемого типа, и по умолчанию это будет int. Возможно, некоторые предполагают, что отсутствующий тип возврата эквивалентен void.
  • Плохие книги/учителя?

Ответ 7

С точки зрения С++ существует 3 источника путаницы:

  • Фундаменталистские компьютерные/настольные программисты, которые фанатично и вслепую проповедуют int main() без фактического знания полной картины в стандарте. C и С++ имеют совершенно разные правила для того, как main() следует объявлять в автономных системах (при программировании встроенных систем с открытым металлом или оперативных систем).
  • Язык C, который исторически имел разные правила по сравнению с С++. А в C правила для main() менялись со временем.
  • Устаревшие компиляторы и стандарты кодирования из темных веков, в том числе программисты, застрявшие в 1980-х годах.

Я рассмотрю каждый источник путаницы в этом ответе.

Программисты ПК/настольные ПК являются проблематичными, так как предполагают, что размещенные системы являются единственными существующими системами и поэтому распространяют неправильную/неполную пропаганду о правильной форме main(), догматически заявляя, что вы должны использовать int main(), неправильно ссылаясь на при этом, если это вообще возможно.

Оба стандарта C и С++ всегда перечисляли два типа систем: автономные и размещенные.

В автономных реализациях void main (void) всегда разрешалось в C. На С++ автономные реализации немного отличаются: автономная реализация может не называть функцию ввода main() или она должна следовать заявленным формам, которые возвращают int.

Даже Bjarne Stroustrup не может привести стандарты или объяснить это правильно/полностью, поэтому не удивительно, что средний программист запутался! (Он ссылается на подпункт размещенной среды и не может ссылаться на все соответствующие его части).

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

Что касается void main (void) в размещенных системах, это происходит из прошлого, где-то в темные века до стандарта ISO C, где все было разрешено.

Я подозреваю, что основным виновником этого является компилятор Borland Turbo C, который уже был лидером на рынке, когда в 1990 году был выпущен ISO C. Этот компилятор разрешил void main (void).

И следует отметить, что void main (void) для размещенных внедрений неявно запрещен в C90 для размещенных систем, не допускается реализация определенных форм. Так что Turbo C никогда не был строго соответствующим исполнением. Тем не менее он по-прежнему используется в школах (особенно в Индии)! Преподавание каждому студенту неправильных стандартов программирования с нуля.

Так как C99, void main (void) и другие формы стали разрешены в C, из-за странного предложения, которое было добавлено: "или каким-то другим способом, определенным реализацией". Это также обсуждается в связанном ответе выше, со ссылками на объяснение C99 и другие части стандарта C, которые предполагают, что размещенная система main() не может возвращать int.

Поэтому в C, void main (void) (возможно) является допустимой формой для размещенных реализаций, учитывая, что компилятор документирует, что он делает. Но учтите, что, поскольку это поведение, определяемое реализацией, именно компилятор определяет, разрешена ли эта форма или нет, а не программист!

В С++ void main (void) не является допустимой формой.