2016-06-27 6 views
5

В качестве эксперимента я просто собрал код для генерации std::array<uint32_t, 256> во время компиляции. Содержимое таблицы является довольно типичной таблицей поиска CRC - о новой новее относится использование функций constexpr для расчета записей, а не для размещения автоматически генерируемой таблицы магии непосредственно в исходном коде.Практические ограничения на количество вычислений constexpr

В любом случае, это упражнение вызвало у меня любопытство: были ли какие-либо практические ограничения на количество вычислений, которые компилятор хотел бы сделать, чтобы оценить функцию или определение переменной во время компиляции? например что-то вроде параметра gcc -ftemplate-depth, создающего практические ограничения на количество оценки метапрограммирования шаблона. (Я также интересно, если там могут быть практические ограничения на длину параметра пакета - который будет ограничивать размер во время компиляции std::array, созданный с использованием std::integer_sequence промежуточного объекта.)

+0

Если я правильно помню, да, есть предел, но он должен быть на порядки больше рекурсивного предел реализации. – MikeMB

ответ

3

Рекомендации по таковые могут быть найдены в [implimits] ¶2:

(2.35)   —   Recursive constexpr function invocations [512]

(2.36)   —   Full-expressions evaluated within a core constant expression [1 048 576]

GCC и Clang позволяют регулировать с помощью -fconstexpr-depth (что флаг вы искали).

Оценка постоянной экспрессии практически выполняется в песочнице, потому что undefined behavior must be preempted by the implementation. Имея это в виду, я не понимаю, почему реализация не могла использовать все ресурсы хост-машины. С другой стороны, я бы не рекомендовал писать программы, компиляция которых требует гигабайт памяти или других необоснованных ресурсов ...

+0

Хорошо, будет ли «Шаблон аргументов в объявлении шаблона [1 024]» также считать длины пакетов параметров? (Я предполагаю, что да, иначе вы могли бы столкнуться с этим ограничением только с очень плохо написанным кодом на C++.) Если это так, это означало бы создание таблицы поиска 'std :: array ' для обработки двух байтов в время, вероятно, не было бы практичным. –

+0

@ DanielSchepler Я не понимаю. – Columbo

+0

В конце таблица создается функцией 'template constexpr std :: array crc_table_impl (uint32_t crc_poly, std :: integer_sequence ) {return {crc_table_entry (crc_poly, I) ...}; } 'передано' integer_sequence', содержащее 0-255. Итак, если бы я попытался сделать то же самое с 'uint16_t', был бы промежуточный шаблон с 65537 аргументами. –