@Skodio29

Как исправить ошибки компиляции Clang под Linux?

Добрый день.
К сожалению, я новичок в С++ и мне не поддается никак решение проблемы.

Сначала я реализовал библиотеку с использование компилятора и сборщика MS.
Затем я перешел на CMake + MSVS.
Далее CMake + CLang.

И все было ок.
Следующим шагом стала попытка сборки CMake + CLang под Linux.

Я получаю 3 проблемы:
use of undeclared identifier 'mbstowcs_s'
use of undeclared identifier 'wcstombs_s'
use of undeclared identifier 'gmtime_s'; did you mean 'gmtime_r'?

Перерыл интернет в поисках решений но тщетно..

Возьмем в пример gmtime_s:
https://en.cppreference.com/w/c/chrono/gmtime

Он доступен с C11, а подсказка гласит о gmtime_r которая C23...

В CMakeLists.txt указано:
set_target_properties(${TARGET_NAME} PROPERTIES
       POSITION_INDEPENDENT_CODE ON 
       CXX_STANDARD 17
       C_STANDARD 11
       CXX_STANDARD_REQUIRED ON
       C_STANDARD_REQUIRED ON
       CXX_EXTENSIONS ON
)


Флаги компиляции:
-fPIC -std=c++17 -fexperimental-library -DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON -stdlib=libc++

Как можно решить эту проблему?
  • Вопрос задан
  • 180 просмотров
Пригласить эксперта
Ответы на вопрос 1
@arteast
gmtime_s - это изначально была нестандартная функция, придуманная Microsoft (хотя и полезная). Ее и прочие "safe"-функции от MS стандартизировали в C11, но отдельным пакетом - Annex K - и как необязательные к реализации. См. на той странице, что вы указали:
As with all bounds-checked functions, gmtime_s only guaranteed to be available if __STDC_LIB_EXT1__ is defined by the implementation and if the user defines __STDC_WANT_LIB_EXT1__ to the integer constant 1 before including .


gcc/glibc и clang/libc не определяют __STDC_LIB_EXT1__ и не поддерживают эти функции.

Также есть функция gmtime_r, которая решает ту же проблему, что и gmtime_s - она гарантированно будет в реализации стандартной библиотеки, но только в C23, т.е. в распоследних версиях компиляторов, которые эту версию поддерживают. Или _может быть_ как расширение - к примеру, на gcc она доступна при наличии макроса __USE_POSIX.

Отвечая на вопрос - не используйте gmtime_s, если хотите хорошую портабельность кода. Либо
  • использовать свежайшее всё, C23 и gmtime_r,
  • либо прагматичный, но несовсемпортабельный подход - впиливать в cmake и код выбор - на msvc библиотеке использовать gmtime_s, на libc/glibc - __USE_POSIX и gmtime_r
  • либо, раз уж вы используете C++, то еще можно подвинуться на C++20 и C++-ные year_month_day и hh_mm_ss.


Похожая история с mbstowcs_s - тот же Annex K и нереализованность на других библиотеках. Используйте mbsrtowcs и иже с ним.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы