Строгий тест соответствия ISO C

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

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

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

Любая справка ценится.

10
задан alecov 9 August 2010 в 20:56
поделиться

5 ответов

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

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

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

(Отредактировано для исправления ошибки, на которую указал caf. Спасибо, caf.)

.
4
ответ дан 4 December 2019 в 02:49
поделиться

Не совсем. Стандарт 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;
}

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

Править:

Почему программа «hello world» не соответствует строго

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

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

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

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

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

3
ответ дан 4 December 2019 в 02:49
поделиться

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

0
ответ дан 4 December 2019 в 02:49
поделиться

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

0
ответ дан 4 December 2019 в 02:49
поделиться

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

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

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

0
ответ дан 4 December 2019 в 02:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: