2016-06-14 1 views
-2

Главный вопрос: как компилятор C обрабатывает несколько определений для функции main в разных исходных кодах? как:Как компилятор C обрабатывает различные определения основных функций?

недействительным основной (аннулируются)

INT основной (аннулируются)

INT основной (интермедиат ARGC, символ * ARGV []) ...

Я не знаю, если это имеет какое-то отношение к манипулированию именами, это происходит только тогда, когда код C связан с кодом C++ без использования extern «C», но также я просто запрашивал с помощью руководства программиста Linux (только простая команда man на оболочке) для функция открыта (man 2 open), и для нее показаны две подписи:

ОТКРЫТО (2) Руководство программиста Linux

ИМЯ

open, creat - open and possibly create a file or device 

СИНТАКСИС

#include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 

    int open(const char *pathname, int flags); 
    int open(const char *pathname, int flags, mode_t mode); 

    int creat(const char *pathname, mode_t mode); 

, как это может работать? Он обрабатывается, как определения основной функции?

+1

Интересно, имеете ли вы в виду несколько деклараций main с разными типами или несколькими определениями. Это поможет, если вы приведете примерный код (ваша собственная программа), поведение которой вам непонятно. Также непонятно, что этот вопрос имеет отношение к [linux] и [C++]. – PJTraill

+1

Название mangling не происходит с именами C, но перегружает имена C++, чтобы учесть ограничения линкеров. Таким образом, это не влияет на то, что делает компилятор C (и, возможно, компоновщик) с вашей программой. – PJTraill

+0

Это не действительный код С. C и C++ являются ** разными ** языками! Даже идентичный синтаксис/грамматика может иметь разную семантику. – Olaf

ответ

2

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

[C99: 5.1.2.2.1/1]:[..] Она должна быть определена с типом возвращаемого int и без параметров: [..]или с двумя параметрами [..]

[C99: 5.1.2.2.1/2]: Если они объявлены, параметры основной функции должны соответствовать следующим ограничениям: [..]

[C99: 3.4.3/1]:неопределенное поведение
поведение, при использовании Непереносимый или ошибочной конструкции программы или ошибочных данных, для которых настоящий стандарт не устанавливает каких-либо требований

4

open фактически не имеют перегруженных или несколько объявлений. Он объявлен как open(const char *pathname, int flags, ...), а третий аргумент считывается с va_arg и интерпретируется как mode_t, когда flags включает O_CREAT.

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

+0

спасибо zneak, отличный ответ – joaopauloribeiro

+0

Я думаю, что я неправильно понял, вопрос о главном заключается не в том, чтобы иметь два или более определений в одном исходном коде, но как компилятор обрабатывает разные определения в разных кодах, например, я могу сделать только пустоту main (void) или int main (void) ... – joaopauloribeiro

+1

@joaopauloribeiro, компилятор отвечает за то, что 'main' корректно вызывается при запуске C. Способ, которым он вызван, должен учитывать, что он может иметь или не иметь аргументы и может или не может возвращать значение (на платформах, где 'main' разрешено возвращать' void' в качестве расширения к стандарту C). Его можно рассматривать как особый случай; вы не обязательно получите такую ​​мягкость с другими функциями. – zneak

3

Типичные реализации языка программирования C толерантны против вызывающего, передающего слишком много аргументов функции.В UNIX-подобные системы, когда код запуска вызовов в main, она проходит три аргумента, как будто main был объявлен

int main(int argc, char *argv[], char *environ[]); 

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

Исторически, функция open работала аналогично: open был объявлен без прототипа, поэтому компилятор не смог проверить, сколько аргументов вы передали. Определение open ожидало три аргумента, если вы только передали два, open будет захватывать все, что находится в стеке для третьего аргумента, который не имеет значения, поскольку третий аргумент не повлиял на результат при вызове open без O_CREAT.

+0

Итак, если функция open захватывает «что угодно» в стеке, она может сломать стек для других функций? – joaopauloribeiro

+1

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

+1

@joaopauloribeiro Поскольку он никогда не перезаписывает свои аргументы, и поскольку 'open' никогда не является верхним фреймом стека, это не проблема. – fuz