Можно было-бы увидеть и понять что было в испорченных строках. В результате (вероятно) восстановить данные полностью (либо ввести вручную), а также пронять причину ошибки (аппаратный сбой или баг в коде postgres).
Первый шаг автора не верный. Всё-таки стоило делать копию всех данных (ибо они не разрушены физически, т.е. нет проблем на HDD).
Не то чтобы вы совсем не правы, но неправы достаточно значительно:
Есть проблемы порожденные отсебятиной M$ (off-topic: Microsoft регулярно кидает и подставляет разработчиков, но некоторые всё еще терпят. Последний пример = "TxF may not be available in future versions of Microsoft Window"). Эти проблемы видны только в некоторых кросс-платформенных сценариях и все уже примерно привыкли что "на виндовс всё через Ж".
В 90% остальных случаях есть GCC и CLANG, где с совместимостью ABI очень хорошо, если не прекрасно.
Есть embedded-like платформы, где местами есть некий зоопарк ABI и проприетарных компиляторов, хотя наблюдается устойчивая тенденция к принятию "ABI как в GCC" в качестве стандарта де-факта. Но в основном тут разные ABI по-определению (для разного порядка байт, PIC/неPIC и т.п.).
Есть какие-то старые платформы (Alpha, DOS) для которых нет актуальных ABI и если вы найдете или соберете компилятор, то ему как-бы не с чем быть несовместимым по ABI.
Поэтому в 99.99% случаев вы получите совместимость по ABI от разных компиляторов, либо вам просто нужно знать что вы хотите и затребовать это задав опции.
приписать "#define _GLIBCXX_USE_CXX11_ABI 0" в системные h-файлы
Прелестно.
На всякий поясню — добавлялось в сборочные контейнеры для сборки "старых" проектов, чтобы совсем не трогать исходники с определениями опций сборки (включая CXX_FLAGS). В частности, так собирались so-шки со "старыми" строками с использованием новых toolchains и без модификации исходников (иногда принципиально важно).
Хотя если принципиально избегать RTFM
Ваш намёк не вполне понятен.
Ради бога не подумайте что я хотел вас задеть и т.п. Просто большинство страданий обычно от незнания.
У Буратино есть два .so, один собран со старым ABI, второй с новым. Расскажите, в какое положение ему надо переключить _GLIBCXX_USE_CXX11_ABI при сборке .cpp-файла, использующего код из обоих .so.
Ну вы же сами прекрасно понимаете, что Буратине так не помочь и ему придется выбрать один из берегов (и какую из so-шек пересобрать). Но только это не страданья, а какая-то недодуманность при сборке so-шек и/или выборе поставщиков.
Т.е. достаточно очевидно, что Буратине нужно определиться с политикой (выбрать одно из трех: только старый стандарт, только новый, либо сборка двух версий so-шек) и просто следовать выбору. Если уже только это приносит Буратине страданья, то его дела плохи — вскорости любые изменения начнут приносить ему боль (включая смены дня и ночи).
Опять-таки не уверен, что я вас правильно понял, но что мешает задействовать свой template<typename T = void> struct less c несколькими перегруженными operator()()?
Возможно я что-то неверно понял/воспринял в вашем комментарии, но показанное изменение определения std::set<> это смена API и ABI одновременно, причем смена API нивелируется/маскируется гибкостью C++.
Поэтому вместо смены ABI в С++14 расширили API добавив template< class K > iterator find( const K& x ) во все релевантные контейнеры из Containers library.
Способов страдать бесконечно много. Наверное, умеючи, можно и Dual ABI задействовать с этой целью ;)
Мне пришлось где-то добавить -D_GLIBCXX_USE_CXX11_ABI=0 в CXX_FLAGS, а пару раз даже для удобства приписать "#define _GLIBCXX_USE_CXX11_ABI 0" в системные h-файлы. Но на страдания это никак не тянет.
Хотя если принципиально избегать RTFM, то можно позабавится ;)
Декорация имен является частью ABI, так как определяет какими именно будут имена сущностей C++ на уровне объектных файлов и DSO.
Если имена получаются не удобными для машины, то увеличиваются затраты на обработку объектных файлов и линковку с библиотеками. Грубо говоря, одна из "проблем" в том, что имена получаются длинные (килобайты из шаблонов) и библиотеки просто пухнут (нередко 10-20% объема файла, после обрезки debug info).
В случае с DSO (aka dll на Windows) добавляются затраты на связывание в runtime. Может показаться неожиданным, но загрузка и запуск большого проекта C++ клубком DSO может приводить к таблицам имен в 10-100 тысяч имен по 20-1000 байт длиной каждой. И всё это потому что про декорацию особенно не думали, тем более "не завезли" visibility, а потом не решились на visibility=hidden по умолчанию. Короче, печаль.
Это и есть несовместимость на уровне ABI. Но только это не проблемы стандарта C++, а результат сознательной преднамеренной (деструктивной) политики M$ (что неоднократно признавали топовые разработчики покинувшие анклав M$, и что легко проследить начиная от \r\n до OID-ов в ActiveDirectory), в том числе и в отношении ABI.
Во-первых dual ABI в GNU libstdc++ как-раз таки обеспечивает совместимость на уровне ABI. Т.е возможно не только запустить старый софт на новой системе, но даже и на новой системе собрать софт, который будет работать на старой (может потребоваться некоторое шаманство для отвязки от symver для некоторых функций glibc).
Во-вторых WG21 не причастен к граблям поставленных M$ с приходом "Universal Runtime" в MSVC (M$ делает подобное регулярно).
Вы путаете (как минимум в примерах) совместимость на уровне API (компилируется или нет) и ABI (работает ли скомпилированное).
Совместимость на уровне API стараются сохранить, но смело ломают когда есть резон. А совместимость на уровне ABI со стороны WG21 менялась (если не ошибаюсь, но другого не помню) только с приходом COW для std::string в C++11. При этом было постелено немало "соломки", поэтому GNU libstdc++ и сейчас обеспечивает работу софта собранного для старого ABI.
При этом WG21 примерно не причастен к массе граблей (например) в разных версиях MSVC.
Меня печалит, что автор (Тит Винтерс) рассуждает и как-бы направляет WG21 в неверном направлении выбора между прогрессом и совместимостью. ABI не может быть вечным, его всё-равно неизбежно когда-нибудь придётся развивать/менять. Выражаясь вульгарно — Не следует обсуждать когда и как лучше кошке отрезать хвост: сегодня, завтра, сразу или частями. Нужно думать про анестезию.
IMHO поэтому WG21 следует сосредоточится (хотя не уверен что это именно их задача) на выработке соглашений/рекомендаций/рецептов для совместного использования нескольких ABI, в том числе для предотвращения смешивания вызовов разных реализаций (один DSO создает новый std::string, а другой DSO разрушает его деструктором от старого std::string).
Это бы не только сняло ряд проблем с развитием C++, но и буквально развязало руки реализаторам (просвистел помидор в сторону компилятора C++ для E2K). А если помечтать, то попутно можно было-бы дожать проблему с "километровыми" идентификаторами в DSO и т.д. и т.п. Но мне кажется, что большинство "коммитетных парней" чураются спускаться до уровня ABI и DSO, предпочитая рассуждать от высоких материях. Поэтому будем ждать когда условные Google или Apple снова занесут гранты реализаторам в обход "коммитетов".
Вы что-то неверно понимаете и пишите примерно ерунду. Пожалуйста внимательно прочитайте обсуждаемый 8.5.1/2, обратив внимание на "the discarded substatement (if any) is not instantiated".
Конечно, для парсинга компилятору необходимо выполнить многие действия аналогичные инстанциации шаблонов, но компилятор может не-персистить результат и не-генерировать программный код. Собственно, в этом суть "discarded substatement".
Тем не менее, в результате такого парсинга после выхода из контекста состояние не меняется, поэтому нельзя сказать что компилятор инстанцировал шаблон (на самом деле он его почти инстанцировал, но задискардил результат).
Теперь я повторю свои вопросы:
Кто-нибудь может прояснить логичекую цепочку, следуя которой if constexpr(false) ограничили до "during the instantiation of an enclosing templated entity" при инсталляции substatement?
Зачем нужно сохранять инсталляцию шаблонов под if constexpr(false) в случаях (not) an enclosing (non)templated entity?
Вы что, хотите меня убедить в том, что невозможно реализовать компилятор, который не будет генерировать какого-либо кода для шаблона инстанцированного только под if constexe(false) или что из-за этого сломается весь остальной C++14-20 ?
Я спрашиваю почему и/или зачем оное написано в стандарте, а вы мне по-сути отвечаете "потому что так написано в стандарте" ;)
Или другими словами — нет сложности в том, чтобы отстрелить генерацию кода или инсталляцию шаблонов под if constexpr(false), но в компиляторах так не сделано согласно букве стандарта, и я пытаюсь выяснить зачем/почему комитет так решил.
Это понятно (что if constexpr не подобие препроцессора), но я не улавливаю дальнейшей логики.
Зачем нужно сохранять инсталляцию шаблонов под if constexpr(false) в случаях (not) an enclosing (non)templated entity? Или что мешает хотя-бы не генерировать код из таких false-instantiated templates?
Почему получилось "у нас есть if constexpr, но тут мы рыбу заворачиваем"?
Для mmap(file) я как-то не увидел в исходниках реализации. Т.е. mmap(/dev/framebuffer) это относительно простая вещь в сравнении с mmap(/mount/ext4/my_2gb_file.dat) и следующей из этого обработкой page-faults, отслеживанием активных workset-ов и paged-out на диск.
Тем не менее, уже понятно что запустить libmdbx в Embox возможно. Осталось понять нужно ли это кому-нибудь. Как будет время я попробую "допилить за пару вечеров".
Для Intel это уже сделано, только усилий (в условных человеко-часах) потрачено на пару порядков больше.
Угу, и дополню:
Самый крутой лайфхак — это просто полностью перейти на Linux.
Синюшный Firefox, только не понятно утонул, много пил или от безнадеги такой синий ;)
Не то чтобы вы совсем не правы, но неправы достаточно значительно:
Поэтому в 99.99% случаев вы получите совместимость по ABI от разных компиляторов, либо вам просто нужно знать что вы хотите и затребовать это задав опции.
На всякий поясню — добавлялось в сборочные контейнеры для сборки "старых" проектов, чтобы совсем не трогать исходники с определениями опций сборки (включая
CXX_FLAGS
). В частности, так собирались so-шки со "старыми" строками с использованием новых toolchains и без модификации исходников (иногда принципиально важно).Ради бога не подумайте что я хотел вас задеть и т.п. Просто большинство страданий обычно от незнания.
Ну вы же сами прекрасно понимаете, что Буратине так не помочь и ему придется выбрать один из берегов (и какую из so-шек пересобрать). Но только это не страданья, а какая-то недодуманность при сборке so-шек и/или выборе поставщиков.
Т.е. достаточно очевидно, что Буратине нужно определиться с политикой (выбрать одно из трех: только старый стандарт, только новый, либо сборка двух версий so-шек) и просто следовать выбору. Если уже только это приносит Буратине страданья, то его дела плохи — вскорости любые изменения начнут приносить ему боль (включая смены дня и ночи).
Опять-таки не уверен, что я вас правильно понял, но что мешает задействовать свой
template<typename T = void> struct less
c несколькими перегруженнымиoperator()()
?Возможно я что-то неверно понял/воспринял в вашем комментарии, но показанное изменение определения std::set<> это смена API и ABI одновременно, причем смена API нивелируется/маскируется гибкостью C++.
Поэтому вместо смены ABI в С++14 расширили API добавив
template< class K > iterator find( const K& x )
во все релевантные контейнеры из Containers library.Способов страдать бесконечно много. Наверное, умеючи, можно и Dual ABI задействовать с этой целью ;)
Мне пришлось где-то добавить
-D_GLIBCXX_USE_CXX11_ABI=0
вCXX_FLAGS
, а пару раз даже для удобства приписать "#define _GLIBCXX_USE_CXX11_ABI 0
" в системные h-файлы. Но на страдания это никак не тянет.Хотя если принципиально избегать RTFM, то можно позабавится ;)
Декорация имен является частью ABI, так как определяет какими именно будут имена сущностей C++ на уровне объектных файлов и DSO.
Если имена получаются не удобными для машины, то увеличиваются затраты на обработку объектных файлов и линковку с библиотеками. Грубо говоря, одна из "проблем" в том, что имена получаются длинные (килобайты из шаблонов) и библиотеки просто пухнут (нередко 10-20% объема файла, после обрезки debug info).
В случае с DSO (aka dll на Windows) добавляются затраты на связывание в runtime. Может показаться неожиданным, но загрузка и запуск большого проекта C++ клубком DSO может приводить к таблицам имен в 10-100 тысяч имен по 20-1000 байт длиной каждой. И всё это потому что про декорацию особенно не думали, тем более "не завезли" visibility, а потом не решились на visibility=hidden по умолчанию. Короче, печаль.
Это и есть несовместимость на уровне ABI. Но только это не проблемы стандарта C++, а результат сознательной преднамеренной (деструктивной) политики M$ (что неоднократно признавали топовые разработчики покинувшие анклав M$, и что легко проследить начиная от \r\n до OID-ов в ActiveDirectory), в том числе и в отношении ABI.
Во-первых dual ABI в GNU libstdc++ как-раз таки обеспечивает совместимость на уровне ABI. Т.е возможно не только запустить старый софт на новой системе, но даже и на новой системе собрать софт, который будет работать на старой (может потребоваться некоторое шаманство для отвязки от symver для некоторых функций glibc).
Во-вторых WG21 не причастен к граблям поставленных M$ с приходом "Universal Runtime" в MSVC (M$ делает подобное регулярно).
Вы путаете (как минимум в примерах) совместимость на уровне API (компилируется или нет) и ABI (работает ли скомпилированное).
Совместимость на уровне API стараются сохранить, но смело ломают когда есть резон. А совместимость на уровне ABI со стороны WG21 менялась (если не ошибаюсь, но другого не помню) только с приходом COW для std::string в C++11. При этом было постелено немало "соломки", поэтому GNU libstdc++ и сейчас обеспечивает работу софта собранного для старого ABI.
При этом WG21 примерно не причастен к массе граблей (например) в разных версиях MSVC.
Меня печалит, что автор (Тит Винтерс) рассуждает и как-бы направляет WG21 в неверном направлении выбора между прогрессом и совместимостью. ABI не может быть вечным, его всё-равно неизбежно когда-нибудь придётся развивать/менять. Выражаясь вульгарно — Не следует обсуждать когда и как лучше кошке отрезать хвост: сегодня, завтра, сразу или частями. Нужно думать про анестезию.
IMHO поэтому WG21 следует сосредоточится (хотя не уверен что это именно их задача) на выработке соглашений/рекомендаций/рецептов для совместного использования нескольких ABI, в том числе для предотвращения смешивания вызовов разных реализаций (один DSO создает новый
std::string
, а другой DSO разрушает его деструктором от старогоstd::string
).Это бы не только сняло ряд проблем с развитием C++, но и буквально развязало руки реализаторам (просвистел помидор в сторону компилятора C++ для E2K). А если помечтать, то попутно можно было-бы дожать проблему с "километровыми" идентификаторами в DSO и т.д. и т.п. Но мне кажется, что большинство "коммитетных парней" чураются спускаться до уровня ABI и DSO, предпочитая рассуждать от высоких материях. Поэтому будем ждать когда условные Google или Apple снова занесут гранты реализаторам в обход "коммитетов".
Вы что-то неверно понимаете и пишите примерно ерунду. Пожалуйста внимательно прочитайте обсуждаемый 8.5.1/2, обратив внимание на "the discarded substatement (if any) is not instantiated".
Конечно, для парсинга компилятору необходимо выполнить многие действия аналогичные инстанциации шаблонов, но компилятор может не-персистить результат и не-генерировать программный код. Собственно, в этом суть "discarded substatement".
Тем не менее, в результате такого парсинга после выхода из контекста состояние не меняется, поэтому нельзя сказать что компилятор инстанцировал шаблон (на самом деле он его почти инстанцировал, но задискардил результат).
Теперь я повторю свои вопросы:
А нам скажет товарищ из "комитета", antoshkka ?
Вы что, хотите меня убедить в том, что невозможно реализовать компилятор, который не будет генерировать какого-либо кода для шаблона инстанцированного только под
if constexe(false)
или что из-за этого сломается весь остальной C++14-20 ?Я спрашиваю почему и/или зачем оное написано в стандарте, а вы мне по-сути отвечаете "потому что так написано в стандарте" ;)
Или другими словами — нет сложности в том, чтобы отстрелить генерацию кода или инсталляцию шаблонов под
if constexpr(false)
, но в компиляторах так не сделано согласно букве стандарта, и я пытаюсь выяснить зачем/почему комитет так решил.Это понятно (что
if constexpr
не подобие препроцессора), но я не улавливаю дальнейшей логики.Зачем нужно сохранять инсталляцию шаблонов под
if constexpr(false)
в случаях (not) an enclosing (non)templated entity? Или что мешает хотя-бы не генерировать код из таких false-instantiated templates?Почему получилось "у нас есть if constexpr, но тут мы рыбу заворачиваем"?
antoshkka ?
Для
mmap(file)
я как-то не увидел в исходниках реализации. Т.е.mmap(/dev/framebuffer)
это относительно простая вещь в сравнении сmmap(/mount/ext4/my_2gb_file.dat)
и следующей из этого обработкой page-faults, отслеживанием активных workset-ов и paged-out на диск.Тем не менее, уже понятно что запустить
libmdbx
в Embox возможно. Осталось понять нужно ли это кому-нибудь. Как будет время я попробую "допилить за пару вечеров".