G++ -std = С++ 0x и совместимость

Я использую g++ 4.4 для компиляции общей библиотеки в linux. Я хотел бы использовать некоторые возможности С++ 11, если я могу в библиотеке, но я не могу обновить версию компилятора или потребовать каких-либо специальных компиляторов для пользователей моей библиотеки.

У меня есть два вопроса, и мне трудно найти окончательный ответ.

  • Если я скомпилирую общую библиотеку с -std = С++ 0x или -std = g++ 0x, я гарантирую, что программа, использующая мою библиотеку, не нуждается в этих коммутаторах (при условии, что у меня нет С++ 0x в файлах заголовков)? Кажется, что это работает, но я не хочу подписываться на тонкие проблемы в будущем.

  • Стандартная библиотека для С++ 11 в g++ 4.4 довольно неполна. Поскольку большая часть стандартной библиотеки имеет только заголовок, а файлы заголовков gnu, как правило, заполнены версиями ifdefs, я бы подумал, что может быть способ использовать более новую версию, по крайней мере, файлов заголовков в libstdС++. Однако я не могу использовать другой .so для этого. Я уверен, что смогу смешать это вместе, но возможно ли сделать что-то подобное правильно?

Спасибо.

Ответ 1

1. Если я скомпилирую общую библиотеку с -std = С++ 0x или -std = g++ 0x, я гарантирую, что программе, использующей мою библиотеку, не нужны эти ключи (при условии, что у меня нет функций С++ 0x в файлы заголовков)? Кажется, что это работает, но я не хочу подписываться на тонкие проблемы в будущем.

Поддержка С++ 11 все еще была экспериментальной в выпуске GCC 4.x(она больше не является экспериментальной для GCC 5). Хотя мы пытались сохранить работу, ответ отрицательный, вы, как правило, не гарантируете, что это будет работать во всех случаях. Существует ряд изменений ABI, вызванных использованием -std=c++0x, которые могут вызвать проблемы для программ, которые смешивают код С++ 03 и код С++ 11, см. http://gcc.gnu.org/wiki/Cxx11AbiCompatibility для более подробной информации. Если ваша библиотека не экспортирует ни один из символов, описанных на этой странице, вы должны быть в порядке.

2. Стандартная библиотека для С++ 11 в g++ 4.4 довольно неполна. Поскольку большая часть стандартной библиотеки имеет только заголовок, а файлы заголовков gnu, как правило, заполнены версиями ifdefs, я бы подумал, что может быть способ использовать более новую версию, по крайней мере, файлов заголовков в libstdС++. Однако я не могу использовать другой .so для этого. Я уверен, что смогу смешать это вместе, но возможно ли сделать что-то подобное правильно?

Нет, нет абсолютно никаких шансов, что это сработает. В заголовках более поздних версий используются функции, не поддерживаемые 4.4, и даже если вы можете их использовать, вам нужно будет использовать новый libstdc++.so. Просто нет.

Заголовки не заполнены версией #ifdefs, почти единственные, которые вы найдете, - это проверки для __GXX_EXPERIMENTAL_CXX0X__, которые определяются с помощью g++ при использовании -std=c++0x, но это не значит, что ваша версия 4.4 поддерживает lambdas, инициализаторы нестатических инициализаторов данных, правильная семантика ссылок rvalue, функции по умолчанию/удаленные функции и т.д., которые более поздние заголовки пользуются либеральным использованием. Вы должны использовать заголовки libstdС++ с той же версией GCC, с которой они пришли.

Короче говоря, если вам нужна правильная поддержка С++ 11, вам нужно использовать более новый компилятор.

Если вы не можете использовать новый компилятор, вы не сможете получить поддержку С++ 11.

Ответ 2

Я бы не попробовал это. Все, что требуется, - это один С++ 11-определенный макрос в заголовке, чтобы изменить определение класса или функции, и ваш конечный пользователь будет нарушать правило одного определения. Это использование может быть чрезвычайно тонким, я думаю.

И затем в аналогичной заметке существует конструктор vector(count, item = T()), который больше не существует в С++ 11 (теперь это два конструктора).

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

Что вы можете сделать, это использовать boost и tr1, чтобы заполнить пробелы в языке, пока вы не сможете использовать новый компилятор и/или иметь возможность требовать от ваших конечных пользователей компиляции с поддержкой С++ 11.