Лучшая практика с sprintf?

Вот такая ситуация:

Мы получили код из внешнего источника, который использует sprintf, например strcat. Нравится:

      char buffer[1024];
sprintf(buffer, "Some text.");
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");

Это выглядит странно. Мы все согласны с тем, что это выглядит странно. Я не об этом спрашиваю. Все мы знаем, что нужно было использовать strcat, и это более просто. Я спрашиваю о потенциальных проблемах, помимо того, что это может выглядеть странно. Мы работаем на RHEL6 и используем gcc 4.9.3.

Спасибо за вашу помощь.

1 ответ

Решение

Функция объявлена ​​как

      int sprintf(char * restrict s, const char * restrict format, ...);

обратите внимание на квалификатор типа.

Согласно стандарту C (7.21.6.6 Функция sprintf)

2 Функция sprintf эквивалентна fprintf, за исключением того, что вывод записывается в массив (указанный аргументом s), а не в поток. В конце написанных символов пишется нулевой символ; он не считается частью возвращаемого значения. Если копирование происходит между перекрывающимися объектами, поведение не определено .

Итак, эти звонки

      sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");

вызвать неопределенное поведение.

Вместо этого звонки можно было бы записать как

      char buffer[1024];
int offset = 0;

offset = sprintf( buffer + offset, "Some text.");
offset += sprintf( buffer + offset, "%s",  "Some more text");
sprintf( buffer + offset, "%s",  "again more text");

Или

      char buffer[1024];
char *p = buffer;

p += sprintf( p, "Some text.");
p += sprintf( p, "%s",  "Some more text");
sprintf( p, "%s",  "again more text");

Что касается квалификатора restrict тогда в общем слова в средствах (6.7.3 квалификаторы типа)

8 Объект, доступ к которому осуществляется через ограниченный указатель, имеет особую связь с этим указателем. Эта ассоциация, определенная в 6.7.3.1 ниже, требует, чтобы все обращения к этому объекту использовали, прямо или косвенно, значение этого конкретного указателя.

Другие вопросы по тегам