Поблочное тестирование на ошибки компилятора

public static class EnumerableExtensions
{
    [Pure]
    public static U MapReduce<T, U>(this IEnumerable<T> enumerable, Func<T, U> map, Func<U, U, U> reduce)
    {
        CodeContract.RequiresAlways(enumerable != null);
        CodeContract.RequiresAlways(enumerable.Skip(1).Any());
        CodeContract.RequiresAlways(map != null);
        CodeContract.RequiresAlways(reduce != null);
        return enumerable.AsParallel().Select(map).Aggregate(reduce);
    }
    [Pure]
    public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
    {
        CodeContract.RequiresAlways(list != null);
        CodeContract.RequiresAlways(list.Count >= 2);
        CodeContract.RequiresAlways(map != null);
        CodeContract.RequiresAlways(reduce != null);
        U result = map(list[0]);
        for (int i = 1; i < list.Count; i++)
        {
            result = reduce(result,map(list[i]));
        }
        return result;
    }

    //Parallel version; creates garbage
    [Pure]
    public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
    {
        CodeContract.RequiresAlways(list != null);
        CodeContract.RequiresAlways(list.Skip(1).Any());
        CodeContract.RequiresAlways(map != null);
        CodeContract.RequiresAlways(reduce != null);

        U[] mapped = new U[list.Count];
        Parallel.For(0, mapped.Length, i =>
            {
                mapped[i] = map(list[i]);
            });
        U result = mapped[0];
        for (int i = 1; i < list.Count; i++)
        {
            result = reduce(result, mapped[i]);
        }
        return result;
    }

}
7
задан LiraNuna 13 July 2009 в 22:10
поделиться

3 ответа

Правильным тестом компилятора и платформы могут быть вариации поведения во время выполнения. Я часто делаю это, воспроизводя небольшие фрагменты поведения, которые существуют в моем производственном коде, и проверяя, что поведение соответствует ожиданиям.

Но в этом случае вам действительно нужен инструмент статического анализа, который проверяет, что код то, что ваши разработчики пишут, следует таким соглашениям, как это. Это, безусловно, подходящий инструмент для сборки. Однако поиск инструмента статического анализа, чтобы найти то, что вы здесь указываете, может быть трудным. Я бы начал со статьи Википедии Список инструментов для статического анализа кода в разделе C / C ++ .

Обратите внимание, что написанный вами код не является "ошибка", это просто ваше соглашение. Это очень хорошее соглашение, но компилятор не ограничивает и не должен ограничивать вас этим соглашением. И инструмент статического анализа тоже. Поэтому вам нужно будет найти тот, который позволит вам настроить, что допустимо, а что нет.

0
ответ дан 7 December 2019 в 18:45
поделиться

Это немного похоже на автоматическое обнаружение, которое происходит, когда вы "./configure" для сборки из исходного кода на машине * nix. Скрипты autoconf создают небольшие программы и пытаются скомпилировать их, чтобы определить, что доступно и поддерживается вашим компилятором.

Вероятно, нецелесообразно повторно использовать что-либо из этого, но вам может понадобиться та же модель. Каждый тест будет иметь свой собственный файл или набор файлов и отдельный файл проекта / make target / и т. Д. Затем ваш тестовый сценарий попытается выполнить каждый тестовый пример и проверить, возникла ли ожидаемая ошибка, либо с помощью grep, либо путем сравнения вывод в базовый вывод, хранящийся вместе с тестовыми примерами.

1
ответ дан 7 December 2019 в 18:45
поделиться

Думаю, главный вопрос сейчас в том, проверяете ли вы, что ваш код или компилятор на этом этапе?

Тестирование компилятора не обязательно плохая вещь ... В прошлом у меня были ошибки маскировки обновлений компилятора, поэтому было бы неплохо убедиться, что вы получаете тот же набор проверок безопасности, который вы ожидаете. много беготни. Ваш модульный тест должен будет создать компилятор, захватить его вывод и проанализировать его на предмет правильного сообщения об ошибке в правильной строке. Это нетривиально и, возможно, того не стоит.

Чуть более простой подход может состоять в том, чтобы сохранить каталог с плохим кодом и заставить скрипт компилировать каждый файл по одному. Имейте там флаг '#ifdef MAKEFAIL', который включает точное условие, которое должно завершиться ошибкой. Убедитесь, что компилятор возвращает 0, если вы не устанавливаете этот флаг, и ненулевое значение, когда вы это делаете. Это предполагает, что компилятор возвращает ненулевое значение при ошибке ... Я не знаю, следует ли MSVC этому правилу.

Третий вариант, который я выброшу для решения проблемы переносимости, - это autoconf. Это может быть сложно настроить, но частично его цель состояла в том, чтобы убедиться, что у вас есть нормальная среда разработки перед компиляцией. Вы можете добавить в него такой тест, и он позволит найти компилятор и попробовать его.

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

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

1
ответ дан 7 December 2019 в 18:45
поделиться
Другие вопросы по тегам:

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