Обнаружение злоупотребления препроцессором C/С++, которое приводит к огромным расширенным размерам кода
Я ищу способ обнаружения или смягчения источника С++, который при предварительной обработке расширяется до огромных размеров, так что у GCC заканчивается память.
Пример кода:
#include <iostream>
using namespace std;
int main() {
#define A30 cout << "hello world";
#define A29 if (1) { A30 } else { A30 }
#define A28 if (0) { A29 } else { A29 }
// ... you get the idea ...
#define A1 if (1) { A2 } else { A2 }
#define A0 if (0) { A1 } else { A1 }
A0
return 0;
}
Компиляция этой программы должна генерировать огромное синтаксически правильное дерево if-else (работает с меньшими версиями, скажем, до A10); если он выполняется, он тривиально печатает одну из строк 2 ^ 30 "hello world" внутри этого дерева. Однако попытка компиляции на 8-гигабайтной машине вызывает невосприимчивое поведение и (через некоторое время) следующее сообщение об ошибке:
internal compiler error: Segmentation fault
A0
^
Можно ли ограничить расширение препроцессора в вышеуказанном случае с помощью GCC 4.9.x или иначе избежать сбоев с такими программами?
Ответы
Ответ 1
Насколько я знаю, нет способа сделать то, что вы пытаетесь достичь, с помощью простой команды gcc.
Путь вокруг него может быть слишком большим, добавив некоторые дополнительные шаги в вашу систему сборки, чтобы убедиться, что фиксация увеличила базу кода на определенный процент.
У вас есть опция (-E) в gcc, которая выводит код после этапа предварительного процессора.
Если у вас есть сборка в commit 1, вы можете сохранить количество строк в этом коммите, запустив gcc с -E и сделав "wc -l" на своем выходе.
При фиксации 2 перед созданием вы делаете то же самое и проверяете, не увеличилось ли количество строк на порог, который вы определили (10%, 20%?)