Короткий ответ:
Нет, при нормальных условиях компилятор никогда не наложит переменные друг на друга.
Хотя флаг -mglobal-merge объединяет переменные, он делает это путем создания структуры (агрегата), где каждая переменная занимает свое уникальное место со своим смещением (offset). С точки зрения памяти они лежат рядом, но не пересекаются.
Однако существуют специфические сценарии, когда использование этого флага может привести к проблемам, которые выглядят как ошибки адресации.
Риски и побочные эффекты
1. Проблемы с Linker Scripts (Скриптами компоновщика)
Это самая частая причина «ошибок». Если ваша система полагается на то, что определенные переменные должны находиться в строго определенных секциях памяти (например, __attribute__((section(".my_special_section")))), объединение может это нарушить.
Что происходит: Компилятор может объединить «обычную» переменную и ту, что должна была быть изолирована, в одну структуру. Если скрипт компоновщика ожидает увидеть отдельные символы для управления памятью, логика может сломаться.
2. Выравнивание (Alignment)
Если у переменных разные требования к выравниванию (например, одна требует выравнивания по 1 байту, а другая по 16), объединение их в одну структуру заставляет компилятор вставлять padding (пустое пространство) между ними.
Если в компиляторе есть баг (что крайне редко для стабильных версий Clang), расчет этого смещения может быть неверным. Но на практике это скорее приводит к падению производительности или Alignment Fault, а не к наложению данных.
3. Нарушение прозрачности для инструментов отладки
Инструменты анализа памяти (например, старые версии AddressSanitizer или специфические проприетарные отладчики) могут запутаться, если они ожидают увидеть индивидуальные символы в таблице символов, а видят один большой блок данных. Это не ошибка в коде, но ошибка в отображении состояния памяти.
4. Проблемы с extern и видимостью
Если одна часть проекта скомпилирована с -mglobal-merge, а другая (ссылающаяся на те же переменные через extern) — без него или с другими настройками видимости, это может привести к ошибкам на этапе компоновки (Link Time), так как оригинальные имена символов могут «исчезнуть», став частью структуры.
Резюме
Вероятность того, что две переменные окажутся по одному и тому же адресу из-за этого флага — практически нулевая. Ошибка почти всегда будет заключаться в:
Нарушении работы Linker Script.
Ошибках при работе с Hardware Mapping (если вы объединяете переменные, привязанные к регистрам периферии).
Совет: Если вы работаете с Embedded-системами или написанием драйверов, где критично расположение каждой переменной, этот флаг лучше отключить (-mno-global-merge), чтобы иметь полный контроль над памятью.