Значение объявления функции - PullRequest
7 голосов
/ 16 февраля 2011

Я читаю файл stdio.h, и я в замешательстве.

Например, есть такая строка:

_CRTIMP FILE* __cdecl __MINGW_NOTHROW fopen (const char*, const char*);

Я знаю, "FILE *" означает возвращаемый тип, и я обнаружил, что _CRTIMP является константой, определенной как

# ifndef _CRTIMP
#  define _CRTIMP  __declspec(dllimport)
# endif

но я все равно не понимаю, для чего это? А что такое остальные строки (__cdecl, __MINGW_NOTHROW)?

Ответы [ 4 ]

6 голосов
/ 16 февраля 2011

__declspec(dllimport) указывает, что функция должна быть импортирована из отдельной библиотеки DLL;Я полагаю, что, в зависимости от настроек статического / динамического связывания CRT, это определяется по-разному.

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

__MINGW_NOTHROW - это #define d, чтобы расширить до __attribute__ ((__nothrow__)), которое является специфичным для MinGW расширением, которое сообщаеткомпилятор, что функция не будет генерировать исключения;это позволяет компилятору выполнять некоторые оптимизации.

Обратите внимание, что все это не стандартные атрибуты C, а специфичные для компилятора / платформы вещи.Опять же, в общем, вы не должны беспокоиться о них, они необходимы для правильной работы CRT, но пока вы не создаете библиотеки, вы можете уйти, не зная о них ничего.:)

5 голосов
/ 16 февраля 2011

Вам следует взглянуть на _mingw.h и руководство по gcc : В случае gcc - или любого другого компилятора, поддерживающего __GNUC__ - применяются следующие определения:

#define __cdecl  __attribute__ ((__cdecl__))
#define __MINGW_NOTHROW __attribute__ ((__nothrow__))

Первый указывает компилятору использовать cdecl x86 соглашение о вызовах ( см. Руководство по gcc ), второй - что функция гарантированно не генерирует исключения C ++ ( см. gcc manual ).

__declspec(dllimport) необходим для работы динамической компоновки ( см. Руководство по gcc ).

1 голос
/ 16 февраля 2011

__declspec(dllimport) сообщает компилятору, что эту функцию необходимо импортировать из DLL, это расширение для Windows. Подробнее см. на этой странице .

Аналогично, __cdecl - это атрибут, который указывает, что функция использует конкретное соглашение о вызовах (а именно то, которое используется C). См. эту страницу .

Я бы предположил, что макрос __MINGW_NOTHROW является синонимом атрибута GCC nothrow, который сообщает компилятору, что рассматриваемая функция не может генерировать исключения. Подробнее см. Документацию .

0 голосов
/ 16 февраля 2011

Тезисы - это объявления, относящиеся к среде или компилятору, который вы используете.

  • __declspec(dllimport) указывает на окнах, что эта функция находится в DLL и должна быть помещена в таблицу импорта сгенерированного исполняемого PE-файла.
  • __cdecl указывает стандартное соглашение о вызовах C и изменяет способ, которым компилятор преобразует функцию для соответствия этому соглашению о вызовах.
  • __MINGW_NOTHROW зависит от вашего компилятора и может деактивировать поддержку исключений.

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

...