Обнаружение злоупотребления препроцессором 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%?)