Как работает это определение функции? - PullRequest
6 голосов
/ 21 ноября 2010

Я сгенерировал хеш-функцию с gperf пару дней назад.То, что я увидел для функции hash, было мне чуждо.Это было что-то вроде этого (я не помню точный синтаксис):

unsigned int
hash(str, size)
   register char* str;
   register unsigned int size;
{
   //Definition
}

Теперь, когда я пытался скомпилировать с помощью компилятора C ++ (g ++), он выдавал ошибки из-за отсутствия strи size заявлено.Но это скомпилировано на компиляторе C (gcc).Итак, вопросы:

  1. Я думал, что C ++ был надмножеством C. Если это так, это должно компилироваться и с компилятором C ++, верно?
  2. Как компилятор C понимаетопределение?str и size необъявлены, когда они появляются впервые.
  3. Какова цель объявления str и size после подписи функции, но перед телом функции, а не после обычного подхода сделать это вв одном из двух мест?
  4. Как заставить эту функцию компилироваться на g ++, чтобы я мог использовать ее в своем коде C ++?Или я должен попытаться сгенерировать код C ++ из gperf?Это возможно?

Ответы [ 3 ]

10 голосов
/ 21 ноября 2010

1.C ++ не является надмножеством, хотя это и не стандартный C.Это объявление функции K & R.См. Каковы основные различия между ANSI C и K & R C?.

4.У gperf действительно есть опция -L для указания языка.Вы можете просто использовать -L C++, чтобы использовать C ++.

2 голосов
/ 21 ноября 2010

Похоже, что это "старая школа" C-код.Объявление типов параметров за пределами круглых скобок, но до открытой скобки блока кода, является пережитком первых дней программирования на C (я не уверен, почему, но я думаю, что это как-то связано с управлением переменными вдизайн стека и / или компилятора).

Чтобы ответить на ваши вопросы:

  1. Называть C ++ "надмножеством" C - несколько неверно.Несмотря на то, что они имеют общие функции синтаксиса, и вы даже можете делать все виды вызовов библиотеки C из C ++, они имеют разительные различия в отношении безопасности типов, предупреждений и ошибок (C более допустим) и параметров компилятора / препроцессора.

  2. Большинство современных компиляторов C понимают унаследованный код (такой, как этот).Компилятор C хранит имена параметров функций вроде «заполнителей», пока их тип не может быть объявлен сразу после имени заголовка функции.

  3. Никаких реальных «целей», кроме как снова, это не появляетсябыть древним кодом, и стиль в те времена был таким.«Нормальный» подход - это IMO - лучший, более интуитивный способ.

  4. Мое предложение:

    хэш unsigned int (зарегистрируйте char * str, зарегистрируйте int без знака размера) {// Определение}

Совет: рассмотрите возможность отказаться от ключевого слова register - оно использовалось в старых программах на C как способ указать, что переменная будет храниться в памятизарегистрироваться (для скорости / эффективности), но в настоящее время компиляторы лучше оптимизируют эту потребность.Я считаю, что современные компиляторы игнорируют это.Кроме того, вы не можете использовать оператор & (адрес) в C / C ++ для переменной register.

2 голосов
/ 21 ноября 2010

Синтаксис старого C для объявления формальных аргументов функции все еще поддерживается некоторыми компиляторами.

Например

int func (x) 
int x 
{

}

- это синтаксис старого стиля (стиль K & R) для определения функции.

Я думал, что C ++ был надмножеством C. Если это так, это должно скомпилироваться и с компилятором C ++, верно?

Nopes! C ++ не является надмножеством C. Этот стиль (синтаксис) объявления / определения функции когда-то был частью C, но никогда не был частью C ++. Поэтому он не должен компилироваться с помощью компилятора C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...