2012-03-19 3 views
1

Я читал из разных источников о том, что в библиотеке C есть много ошибок, проблем и ошибок дизайна. Некоторые из них относятся к функциям обработки строк, некоторые с ввода-выводами и т.д.Проблемы со стандартной библиотекой C?

Это правда? Если да, может ли кто-нибудь перечислить некоторые из наиболее распространенных известных проблем?

Примечание: Я говорю о ISO C Library.

+4

Отсутствует код ошибки; есть только багги, которые пишут код. –

+1

Одна проблема - это, как я помню, некорректная некорректность некоторых строковых функций, взятие константной строки и возвращающая указатель на неконстантную. Проверь это. –

+0

Какие источники это? И говорят ли они о * дизайне * стандартной библиотеки или конкретной * реализации * стандартной библиотеки? –

ответ

2

Off верхней части моей головы, вот несколько известных дизайна вопросы:

  1. Входные функции, такие как gets (устаревшее в C99, пошел в C11, но по-прежнему скрывается в Бог знает, как много устаревшего кода) scanf с использованием простого спецификатора преобразования %s и т. д., который может перехватить свой целевой буфер;

  2. Функции, такие как strtok, которые используют статические буферы для хранения состояния между вызовами и, как таковые, являются не реентерабельными;

Насколько реализации вопросов, я не думаю, что кто-то, кто нуждается в хороший ПГСЧЕ довольно функцией фондового rand в большинстве реализаций.

+2

Учитывая, как давно писал Дональд Кнут о бессмысленном копировании плохого кода PRNG, действительно замечательно, что он еще не остановился ... –

+0

'scanf, используя простой% s спецификатор преобразования'. Черт, я много использовал в своем коде. Думаю, мне придется переписать части. Какие-нибудь хорошие альтернативы? – ApprenticeHacker

+1

@IntermediateHacker: либо помещать ширину поля перед спецификатором '% s' (например,'% 20s' для чтения в 21-символьный буфер, сохраняя место для завершения 0), либо использовать 'fgets'. –

2

Самой большой проблемой в ISO C90 и C99 является, вероятно, gets, которая подвержена переполнению буфера. Фактически, он, кажется, был удален из нового стандарта C11.

Функция ISO C для получения временного файла, tmpnam, уязвима для условий гонки на многопользовательских платформах. Стандарт POSIX определяет функцию mkstemp, что является более безопасным.

Кроме того, многие из строковых функций, таких как strchr, не являются безопасными по типу; они берут const char*, но возвращают char* в тот же буфер, поэтому, используя их, вы можете неявно лить const. Однако избегать этого - вопрос тщательного программирования; строковые функции не являются по своей сути небезопасными в способе, которым являются gets и tmpnam.

Наконец, многие функции, такие как strcpy, strcat и sprintf делать никаких ограничений не проверяя, но так как они не имеют дело с внешним входом, как gets делает, они могут использоваться безопасным образом. snprintf - более безопасная альтернатива sprintf с C99.

+2

Дело в том, что язык - это больше, чем просто код. Язык требует, чтобы вы присваивали const-sourced 'strchr'' const char * '; на языке просто не хватает выразительности для обеспечения этого. –

+1

@KerrekSB: вы правы, но я все еще думаю, что функции строк заслуживают перечисления. Добавлена ​​заметка о тщательном программировании. –

+0

@KerrekSB: сохранение адреса неизменяемых объектов в переменных, отличных от 'const', отлично, если вы не пытаетесь изменить объект; то же самое происходит с эффективными типами: в некотором смысле, C на самом деле * * * строго типизирован - это просто, что система типов необоснованна, а ограничения типа только вступают в силу при оценке, приводя к неопределенному поведению в случае нарушения ... – Christoph