Запретить Apple clang добавлять пути Xcode в стандартные пути включения

#c #xcode #macos #clang

#c #xcode #macos #clang

Вопрос:

Похоже, что Apple clang волшебным образом включает файлы заголовков Xcode, которые конфликтуют с моим кодом. Например, они определяют stoi() , в то время как стандартные заголовки C этого не делают. Clang не делает этого на других платформах, например, FreeBSD.

Пример ошибки в Mac OS:

 $ clang -I. -I../../../include -c compile.cpp
compile.cpp:949:18: error: call to 'stoi' is ambiguous
                            arg.iValue = stoi(current.token);
                                         ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c  /v1/string:4019:37: note:
      candidate function
_LIBCPP_FUNC_VIS int                stoi  (const stringamp; __str, size_t* ...
                                    ^
  

Эта компиляция отлично работает на FreeBSD.

Проблема заключается в том, что в дополнение к стандартным заголовкам C в /usr/include/c , Apple clang включает заголовки в цепочку инструментов приложения Xcode. Есть ли какой-нибудь способ отключить это без использования -nobuiltininc флага?

Комментарии:

1. Скомпилируйте, используя --stdlib=libstdc вместо --stdlib=libc . Реализацией libc является c 11, что означает, что эта процедура будет присутствовать. Это актуальная проблема, с которой вам, вероятно, придется столкнуться, поскольку более новая версия gcc также будет определять процедуру, если вы скомпилируете с --std=c 11

2. @Petesh — это именно то решение, которое мне было нужно. Вы должны опубликовать свой комментарий в качестве ответа. Я отмечу, что это принято. Большое спасибо!

3. показать полную ошибку. Вероятно, у вас есть конфликт stoi , от которого вы хотели бы избавиться.

4. У меня есть конфликт stoi , но я не хочу от него избавляться. Мы не используем C 11 во FreeBSD — пока. Когда мы это сделаем, тогда да. Я просто пытаюсь сделать так, чтобы моя среда разработки на моем Mac работала достаточно, чтобы я мог разрабатывать локально.

Ответ №1:

Библиотека C по умолчанию для более новых версий clang на OSX libc , которая является довольно полной реализацией стандарта C 11. Все заголовки относятся к C 11, и в них нет условных разделов для удаления методов, которые должны быть доступны только в этом стандарте (например, попытка компиляции с использованием --std=c 03 не дает желаемого эффекта.

Версия stdlib , которая присутствует в среде Apple, не имеет этой проблемы, поскольку (1) это не полная реализация стандарта C 11, и (2) вы действительно можете компилировать для более старых стандартов c .

В результате, если вы компилируете с использованием --stdlib=libstdc , вы компилируете с использованием заголовков и библиотек GNU standard library, у которых нет проблем с определением std::stoi (и других подпрограмм, если я правильно интерпретирую вопрос).

Имейте в виду, однако, что вы должны скомпилировать каждый элемент c вашего проекта с этим флагом, так как в противном случае вы получите код, который был скомпилирован с использованием разных стандартных библиотек, и они не будут связаны друг с другом.

Реальная проблема, однако, заключается в том, что если вы начнете использовать функции C 11 и начнете явно компилировать с --std=c 11 , то вы, вероятно, столкнетесь с этой проблемой в какой-то момент в будущем и с gcc. Более новые версии компилятора поддерживают больше стандарта C 11, и поэтому эта процедура будет определена в заголовках, и вы вернетесь к исходной точке.