Строгий тест на соответствие ISO C - PullRequest
10 голосов
/ 10 августа 2010

В настоящее время я работаю над проектом C, который должен быть достаточно переносимым в различных средах здания.Проект нацелен на POSIX-совместимые системы в размещенной среде C.

Один из способов достижения хорошей степени переносимости - это кодирование в соответствии с выбранным стандартом, но трудно определить, является ли данный модуль переводастрого соответствует ISO. Например, он может нарушать некоторые ограничения перевода или полагаться на неопределенное поведение без каких-либо диагностических сообщений из среды компиляции.Я даже не уверен, можно ли проверить на строгое соответствие крупных проектов.

Имея это в виду, существует ли какой-либо компилятор, инструмент или метод для проверки на строгое соответствие ISO Cв соответствии с данным стандартом (например, C89 или C99) единицы перевода?

Любая помощь приветствуется.

Ответы [ 5 ]

4 голосов
/ 10 августа 2010

В общем случае невозможно найти неопределенное поведение во время выполнения. Например, рассмотрим

void foo(int *p, int *q)
{
    *p = (*q)++;
    ...

, который не определен, если p == q. Может ли это произойти, не может быть определено заранее без решения проблемы остановки.

(Отредактировано, чтобы исправить ошибку. Каф указал. Спасибо, каф.)

3 голосов
/ 10 августа 2010

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

#include <stdio.h>

int main(int argc, char **argv) { 
    int i;
    for (i=1; i<argc; i++)
        fprintf(stderr, "`%s`: Translation limit (potentially) exceeded.\n", argv[i]);
    return 0;
}

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

Редактировать:

Почему программа "Привет, мир" не совсем соответствует

Во-первых, стоит переформулировать определение «строго соответствующего»: «В строго согласованной программе должны использоваться только те функции языка и библиотеки, которые указаны в настоящем международном стандарте. 2) Она не должна создавать выходные данные, зависящие от каких-либо неопределенных , неопределенное или определяемое реализацией поведение, и не должно превышать какого-либо минимального предела реализации. "

На самом деле существует число причин, по которым «Hello, World» не совсем соответствует. Во-первых, как подразумевается выше, минимальные требования к пределам реализации совершенно бессмысленны - хотя должна быть некоторая программа, которая удовлетворяет определенным пределам, которые будут приняты, нет другая программа должна быть принятым, даже если он даже не приближается ни к одному из этих ограничений. Учитывая то, как сформулировано требование, остается открытым вопрос (в лучшем случае), существует ли такая вещь, как программа, которая не превышает какого-либо минимального предела реализации, поскольку стандарт на самом деле не определяет никаких минимальных пределов реализации.

Во-вторых, во время фазы 1 перевода: «Многобайтовые символы физического исходного файла отображаются в соответствии с реализацией определенным набором символов ...» (§5.1.1.2 / 1). Так как "Привет, мир!" (или любой другой вариант, который вы предпочитаете) поставляется в виде строкового литерала в исходном файле, он может (есть) отображаться в соответствии с реализацией в исходный набор символов. Реализация свободна решать, что (для идиотского примера) строковые литералы будут кодироваться в ROT13, и, пока этот факт должным образом задокументирован, это совершенно законно.

В-третьих, вывод обычно записывается через stdout. stdout - текстовый поток. Согласно стандарту: «Символы могут быть добавлены, изменены или удалены при вводе и выводе, чтобы соответствовать различным соглашениям для представления текста в среде хоста. Таким образом, между символами не должно быть взаимно-однозначного соответствия. в потоке и во внешнем представлении. " (§7.19.2 / 2) Таким образом, реализация может (например) выполнять сжатие Хаффмана на выходе (в понедельник, среду или пятницу).

Итак, у нас есть (как минимум) три разных точки, в которых выводится «Hello, World!» зависит от характеристик, определяемых реализацией - любая из них помешала бы ей соответствовать определению строго соответствующей программы.

0 голосов
/ 10 августа 2010

Удачи с этим. Старайтесь избегать целых чисел со знаком, потому что:

int f(int x) 
{
 return -x;
}

может вызвать UB.

0 голосов
/ 10 августа 2010

Вы можете начать с gcc -std=c99 или gcc -ansi -pedantic.

0 голосов
/ 10 августа 2010

gcc имеет уровни предупреждения, которые попытаются определить различные аспекты соответствия ANSI.Но шляпа - только отправная точка.

...