Почему не определено главное `main (std::vector <std::string> args)`?

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

Если вы используете С++, не должно быть предпочтительного определения main что-то вроде:

int main(std::vector<std::string> args)

?

Есть уже несколько определений main для выбора, почему нет версии, которая находится в духе С++?

Ответы

Ответ 1

Опасность, которая приходит мне в голову, заключается в том, что, когда вы разрешаете сложные типы, вы получаете риск исключения исключений в конструкторе типов. И, поскольку язык в настоящее время разработан, абсолютно невозможно исключить такое исключение. Если бы было решено, что такие исключения должны быть пойманы, то для этого потребуется значительно больше работы, как для комитета, так и для составителей компиляторов, что делает все это более неприятным, чем просто "allow std::vector<std::string>>".

Могут быть и другие проблемы. Вся "несовместимая с временем выполнения" кажется мне чем-то вроде красной селедки, учитывая, что теперь вы можете предоставить в основном те же функции с макросами. Но что-то вроде этого более активно.

Ответ 2

Поскольку С++ был разработан (почти) обратно совместим с кодом C.

Бывают случаи, когда код C будет разбит на компилятор С++, но они довольно редки, и в целом есть веская причина, почему требуется этот полом.

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

Другая причина в том, что std::vector - это библиотека, а не часть основного языка. Итак, вам нужно будет #include <vector> в каждой программе на С++.

И, конечно же, в первые годы существования С++ не было вектора. Поэтому, когда вектор был добавлен на язык, конечно, они могли бы изменить подпись main, но тогда они сломали бы не только код C, но также и любую существующую программу на С++.

Стоит ли это?

Ответ 3

Есть и другая причина, помимо совместимости с C. В С++ стандартная библиотека должна быть полностью необязательной. Нет ничего о самом языке С++, который заставляет вас использовать вещи из стандартной библиотеки, например std::string и std::vector, и это полностью по дизайну. Фактически, по дизайну вы должны иметь возможность использовать некоторые части стандартной библиотеки, не используя другие (хотя это привело к некоторым обычно раздражающим вещам типа std::ifstream и std::ofstream, работающим на const char* C- а не на объектах std::string).

Теория состоит в том, что вы должны иметь возможность использовать язык С++ и использовать любую библиотеку объектов, контейнеров и т.д., которые вы хотите с ней, будь то стандартная библиотека или некоторая собственная библиотека (например, Qt, MFC), или что-то, что вы создали сами. Определение main для принятия аргумента, состоящего из типов, определенных в стандартной библиотеке, поражает эту цель дизайна.

Ответ 4

Потому что это заставит вас включить <vector> и <string>.

Ответ 5

Как @jalf, я иногда нахожу себя в написании

int main(int argc, char** argv) {
    std::vector<std::string> args(argv, argv+argc);

Но да, как и все говорили, main должен быть C-совместимым. Я рассматриваю его как интерфейс для среды выполнения ОС, которая (по крайней мере, в системах, которые я использую) написана на C.

Хотя некоторые среды разработки способствуют замене, например wmain или _tmain. Вы можете написать свой собственный компилятор /IDE, что будет способствовать использованию int vmain(const std::vector<std::string>& args).

Ответ 6

Потому что С++ существовал задолго до того, как был стандарт С++, и был построен в значительной степени на C. И, как и оригинальный стандарт ANSI C, кодификация существующей практики была важной его частью.

Нет смысла менять что-то, что работает, особенно если оно сломает весь существующий код.

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

Ответ 7

В принципе, оставаться совместимым с C. Если бы мы отказались от этого, main() переместился бы в класс.

Ответ 8

Множественные определения main() не являются действительно множеством определений. Есть три:

  • int main(void) (C99)
  • int main(int argc, char *argv[]) (C99)
  • int main(int argc, char *argv[], char *envp[]) (POSIX, я думаю)

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

У вас не может быть extern "C" int main(std::vector<std::string> argv), если макет памяти не будет волшебным образом совместим в переносном режиме. Время выполнения вызовет main() с неправильными аргументами и завершится сбой. Там нет простого пути.

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

Для удовольствия, void main (void).

Ответ 9

Я попробую объяснить в наилучшем возможном предложении.

С++ был разработан для обратной совместимости с C и std::vector был включен в библиотеку, которая была включена только в С++.

Кроме того, программы С++ и C были разработаны для запуска в оболочках или командных строках (windows, linux, mac) и аргументах передачи ОС в программу в виде массива String. Как бы ОС действительно переводила векторы?

Что я думаю о самой причине, не стесняйтесь критиковать ее.