Иллюстрированный самоучитель по практике программирования

Язык

Компиляторы ANSI С должны воспринимать и прежний синтаксис, но мы настоятельно рекомендуем вам забыть об этом и всегда писать прототипы для всех функций. Это сделает код более безопасным, вызовы функций будут полностью проверены на совместимость типов, и при изменении интерфейса компилятор это отловит. Если в коде употребляется вызов:

func(7, PI);

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

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

Избегайте неоднозначных конструкций языка.
Как мы уже говорили, некоторые вещи в стандартах умышленно оставлены неопределенными для того, чтобы предоставить создателям компиляторов большую свободу для маневра. Список таких неопределенностей обескураживающе велик.

Размеры типов данных.
Размеры основных типов данных в С и C++ не определены. Не существует никаких гарантированных свойств, кроме общих правил, гласящих, что:

sizeof(char) <= sizeof (short) <= sizeof(int)
<= sizeof(long) sizeof(float)
<= sizeof(double) %

А также, что char должен иметь как минимум 8 битов, short и int – как минимум 16, a long – по крайней мере 32. Не требуется даже, чтобы значение указателя умещалось в inj.

Проверить, какие значения использует конкретный компилятор, достаточно просто:

Иллюстрированный самоучитель по практике программирования › Переносимость › Язык

Результат будет одинаковым для большинства распространенных машин:

char 1, short 2, int 4, long 4, float 4, double 8, void* 4

Однако возможны и другие значения. Некоторые 64-битовые машины покажут такие значения:

char 1, short 2, int 4, long 8, float 4, double 8, void* 8

А ранние компиляторы под PC показали бы такое:

char 1, short 2, int 2, long 4, float 4, double 8, void* 2

Во времена появления PC аппаратура поддерживала несколько видов указателей. Для того чтобы справиться с такой неразберихой, были придуманы модификаторы указателей far и near, ни один из которых не входит в стандарт, но до сих пор эти ключевые слова-призраки появляются во многих компиляторах. Если ваш компилятор может менять размеры базовых типов или если вы имеете доступ к машинам, поддерживающим другие размеры, постарайтесь скомпилировать и оттестировать вашу программу при таких новых для нее условиях.

Стандартный заголовочный файл stddef.h определяет ряд типов, которые могут помочь с переносимостью. Наиболее часто используемый из них – size_t, который представляет собой тип беззнакового целого, возвращаемого оператором sizeof. Значения этого типа возвращаются функциями типа strlen и во многих функциях, включая mallос, используются в качестве аргументов.

Наученная чужим горьким опытом, Java четко определяет размеры всех своих базовых типов: byte – 8 битов, char и short – 16, int – 32 и long – 64 бита.

Мы не будем рассматривать набор проблем, связанных с вычислениями с плавающей точкой, потому что разговор об этом достоин отдельной книги. Скажем только, что большинство современных машин поддерживают стандарт IEEE на аппаратуру для плавающей точки, и, следовательно, для них свойства арифметики с плавающей точкой определены достаточно четко.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.