Это допустимый код C, но не действительный код на C ++?

В какой-то библиотеке я использую (написанную на C) ее

StorePGM(image, width, height, filename) char *image; int width, height; char *filename; { // something something } 

Все функции определены таким образом. Я никогда не видел таких определений функций в своей жизни. Они кажутся действительными для MSVC, но когда я компилирую его как C ++, он дает ошибки.

Что это? какая-то старая версия C?

Да. K & R, pre-standard C. Избегайте использования.

До стандарта ANSI C 1989 года C не имел прототипов (объявления функций, определяющие типы параметров); эти декларации и определения старого стиля были доступны всем.

В 1989 году стандарт ANSI C (который по существу стал стандартом ISO ISO 1990) представил прототипы. Если я правильно помню, идея действительно исходила из C ++ (который еще не был стандартизирован в то время). Старые декларации и определения остаются законными, так что старый код все еще может быть скомпилирован. В стандарте 1989 года также говорится, что декларации старого стиля были «устаревшими», что означает, что они могут быть удалены в будущей версии стандарта.

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

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

C ++, с другой стороны, никогда (?) Не поддерживал ничего, кроме прототипов, как объявления функций; Stroustrup не беспокоился о совместимости со старым кодом C.

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

Заметим, что, по крайней мере, в C это определение:

 int main() { /* ... */ } 

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

 int main(void) { /* ... */ } 

(C ++ также принимает эту форму для совместимости с C, но к тому моменту, когда вы пишете main , вы уже должны решить, какой язык вы используете.)

Да, это K & R-Style. (Kernighan & Ritchie являются изобретателями C) См. Также http://www.lysator.liu.se/c/bwk-tutor.html для примеров этого стиля до ANSI.