Два вопроса по основному

A. Допустима ли следующая попытка определить точку входа «main» автономной программы C ++?

namespace{
 extern int main(){return 0;}
}

Насколько я понимаю, он удовлетворяет всем критериям «main» в стандарте C ++ (внешняя связь, доступная в глобальном пространстве имен из-за неявной директивы using).

Итак, эта программа плохо сформирована и почему? Есть ли ссылка на стандарт?

Б. Я обсуждал EXIT_FAILURE и EXIT_SUCCESS, но не могу сделать вывод, всегда ли EXIT_SUCCESS должен быть 0. Это потому, что согласно Стандарту исключение оператора возврата в 'main' эквивалентно возврату 0. Так что, я полагаю, EXIT_SUCCESS должен всегда быть 0.

$ 18.3 - «Если статус равен нулю или EXIT_SUCCESS, возвращается форма успешного завершения статуса, определяемая реализацией».


person Chubsdad    schedule 08.09.2010    source источник


Ответы (3)


A. Допустима ли следующая попытка определить точку входа «main» автономной программы C ++?

Нет. Стандарт C ++ гласит: «Программа должна содержать глобальную функцию с именем main» (§3.6.1 / 1). В вашей программе функция main не находится в глобальном пространстве имен; он находится в безымянном пространстве имен.

Неявная директива using позволяет искать и использовать только имена из безымянного пространства имен во включающем пространстве имен; он не добавляет эти имена к охватывающему пространству имен. В частности, «using-directive не добавляет никаких членов в декларативную область, в которой она появляется» (§7.3.4 / 1).

Эта программа плохо сформирована и почему?

Программа не обязательно плохо сформирована. Нет правила против наличия функции с именем main в пространстве имен, отличном от глобального пространства имен; такая функция не является функцией main. namespace { int main(); } и int main() - две разные функции, и в правильно сформированной программе они могут быть обе.

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

B. Я обсуждал EXIT_FAILURE и EXIT_SUCCESS, но не могу сделать вывод, всегда ли EXIT_SUCCESS должно быть 0.

Не требуется, чтобы EXIT_SUCCESS расширялся до 0. Стандарт C просто говорит, что в <stdlib.h>,

Определены макросы ..._ 15_ и EXIT_SUCCESS, которые расширяются до целочисленных констант, которые могут использоваться в качестве аргумента функции exit для возврата неудачного или успешного состояния завершения, соответственно, в среду хоста (C99 §7.20 / 3).

(Поскольку эти два макроса определены в <cstdlib>, стандарт C содержит для них спецификацию).

person James McNellis    schedule 08.09.2010
comment
Видите, это то, что я знал всегда; что точка входа (по крайней мере, в C / C ++) - это глобальная функция с именем main. Однако в C ++ Primer, 4-е издание на странице 717 говорится, что нужно написать программу, которая ... сделает эту программу членом другого пространства имен ... Что за ?! Вот почему я попробовал (безуспешно) и оказался здесь, пока искал. - person Synetech; 17.12.2010
comment
Да, этот ответ описывает то, что я знал давно. Тем не менее, в книге указано, что читатель помещает программу (например, main ()) в пространство имен для этого упражнения. Я проверил, и в списке опечаток об этом нет упоминания, поэтому я не уверен, что он предназначен для компиляции или запуска, это просто упражнение по использованию пространств имен. - person Synetech; 21.12.2010

Здесь namespace { } - это анонимное пространство имен - идея состоит в том, что ничто не должно уходить оттуда в глобальное пространство имен - на практике все это должно иметь префикс, который не будет конфликтовать с другими единицами перевода. Вы сделали это extern, но не extern "C", поэтому специальное правило о том, что main не искажается, не защитит его, и символ не будет удовлетворять требованиям связывания. В любом случае, помещать что-то внешнее в анонимное пространство имен - это просто заблуждение. Вы постоянно стараетесь изо всех сил, чтобы увидеть, как можно превратить Стандарт в странные искажения :-). Любопытно - есть ли причина? Вы заинтересованы в этом с академической точки зрения, или реализуете компилятор или набор тестов компилятора или что-то в этом роде?

Смотрите, вы добавили обсуждение EXIT_SUCCESS и EXIT_FAILURE к своему вопросу. Ключевым моментом здесь является то, что вы можете использовать их из main или exit () и знать, что они будут работать в любой операционной системе. Для возврата 0 не проблема, используете ли вы EXIT_SUCCESS, 0 или позволяете основному "провалиться". ОС может на самом деле вернуть 0 операционной системе, а может и не вернуть ... может случиться так, что время выполнения сопоставляет это с каким-то другим значением, которое означает «успех» в этой ОС. Но в случае сбоя - если вы вернете произвольное значение, отличное от 0, оно может обойти это сопоставление и либо указать что-то отличное от простого сбоя, либо совпадать со значением успеха. Значения также могут обрабатываться по-разному в разных операционных системах: многие (например, Linux) удаляют из вашего возвращаемого значения все, кроме 8 наименее значимых битов, так что возвращение 256 эквивалентно возвращению 0. Вот почему не рекомендуется гадать. при подходящем значении, отличном от 0.

person Tony Delroy    schedule 08.09.2010
comment
При чтении en.wikipedia.org/wiki/Main_function_(programming) заявление Компилятор Sun Studio 11 C ++ позволяет использовать main в неглобальном пространстве имен, а также в качестве функции-члена (класса или экземпляра). вызвало это мышление. - person Chubsdad; 08.09.2010
comment
Я не занимаюсь чем-либо, связанным со стандартами / компилятором / набором тестов для компилятора и т. Д., Хотя мне бы очень хотелось. Я просто увлечен C ++ - person Chubsdad; 08.09.2010
comment
Итак, этот абзац Википедии начинается с main, он должен находиться в глобальном пространстве имен (т.е. :: main) и не может быть функцией-членом (класса или экземпляра), хотя имя не зарезервировано и может использоваться для других (обычных) функций-членов или функции, не являющиеся членами. Компилятор Sun Studio 11 C ++ .... Похоже, они говорят, что Sun допускает исключение из Стандарта. - person Tony Delroy; 08.09.2010
comment
И Википедия - не мой обычный источник информации о соответствии стандартам. - person Martin York; 08.09.2010

A. Когда я пытаюсь запустить ваш код в Visual C ++ 2010, я получаю следующее:

Ошибка 1 ошибка LNK1561: точка входа должна быть определена

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

Статус выхода

Значение, возвращаемое основной функцией, становится статусом завершения процесса, хотя стандарт C приписывает конкретное значение только двум значениям: EXIT_SUCCESS (традиционно ноль) и EXIT_FAILURE. Значение других возможных возвращаемых значений определяется реализацией.

Подробнее об этом здесь.

person Leniel Maccaferri    schedule 08.09.2010
comment
Да, это тот сайт, который я читал и который вызвал этот вопрос (мои комментарии в сообщении Тони). - person Chubsdad; 08.09.2010
comment
из §3.6.1 / 2, эта функция не должна быть перегружена., поэтому на самом деле ее можно использовать для других xxx или нечленовских функций, это не совсем правильно (я вижу, вы скопировали это из Википедии ... рискованно ;-)) . - person Tony Delroy; 20.06.2011