Skip to content

conf.h: глобальные #define (ssize_t/min/max/__func__) ломают системные заголовки на clang-cl при неудачном порядке включения #3374

@kvirund

Description

@kvirund

Суть

src/engine/core/conf.h в ветке _WIN32 определяет глобальные макросы до подключения стандартной библиотеки:

#define ssize_t int
#define socklen_t int
#undef min  / #define min min
#undef max  / #define max max
#define __func__ ""
#define mkdir(str, int) _mkdir(str)

Это глобальное загрязнение препроцессора. Если любой TU включает проектный заголовок (тянущий conf.h) раньше системных заголовков, эти макросы «остывают» в стандартную/интринсик-библиотеку и могут её сломать.

Как проявилось

В #3373 новый тест tests/file_crc.cpp (первая строка — #include "utils/file_crc.h") оказался первым в unity-чанке. Цепочка file_crc.h → conf.h → sysdep.h → structs.h → <vector> → … → clang intrin.h → mmintrin.h собиралась clang-cl'ом, и __v2si (MMX-вектор из двух int) схлопывался в скалярный int:

mmintrin.h: error: cannot initialize a parameter of type
'…__vector_size__(2 * sizeof(int)) int' with an rvalue of type '__v2si' (aka 'int')

Job windows / Clang / Base падал. На master он зелёный — там первым в чанке был другой тест, подключающий <gtest/gtest.h> первой строкой, поэтому системные/интринсик-заголовки включались в чистом состоянии.

Это не баг Meson и не компилятора

Unity-сборка — лишь катализатор (переставила порядок файлов в чанке). Эффект воспроизведётся и без Meson: любой обычный .cpp, который на clang-cl/Windows включает проектный заголовок раньше системного, упрётся в то же. Корень — гигиена заголовков: conf.h гадит в глобальные макросы перед системной библиотекой.

Обход (уже в #3373)

Коммит 2deb69b: в новых тест-файлах <gtest/gtest.h> подключается первым — системные/интринсик-заголовки включаются в чистом виде. Это лечит симптом, не причину.

Что чинить по-настоящему

  • conf.h не должен определять глобальные макросы: ssize_t/socklen_ttypedef; min/max нейтрализовать через NOMINMAX + <algorithm>, а не #define; __func__ "" — убрать/загардить; mkdirinline-обёртка.
  • Как минимум сам conf.h должен подтягивать нужные системные заголовки до своих дефайнов, чтобы порядок включения в TU не имел значения.
  • Точный макрос-виновник для __v2si не изолирован (clang-cl локально не воспроизводится) — нужен прогон/бисект на Windows.

Refs #3373

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions