Страницы

Поиск по вопросам

Показаны сообщения с ярлыком mingw-w64. Показать все сообщения
Показаны сообщения с ярлыком mingw-w64. Показать все сообщения

пятница, 14 февраля 2020 г.

Строгий алиасинг в MinGW-w64

#cpp #шаблоны_с++ #mingw #mingw_w64


При компиляции с MinGW-w64 этого простого кода:

#include 
#include 
#include 

template 
void readWithSep(){
    std::istringstream sLine;
    sLine.str("hello");
    std::string line;
    while(std::getline(sLine, line)){
        std::cout<();
}


выдаётся ошибка: 


  доступ по указателю с приведением типа нарушает правила перекрытия
  объектов в памяти [-Werror=strict-aliasing] 
  
  while(std::getline(sLine, line)){


Компилирую так:


  i686-w64-mingw32-g++ -std=c++17 -W -Wall -Wextra -pedantic -Werror -O3
  file.cpp


Почему возникает эта ошибка и как её исправить? Здесь же вроде никаких преобразований
типов не происходит. Странно, что g++ это компилирует без ошибок (с теми же флагами)

Полный вывод компилятора:


  file.cpp: В функции «void readWithSep()»:
  
  file.cpp:10:35: ошибка:
  доступ по указателю с приведением типа нарушает правила перекрытия
  объектов в памяти [-Werror=strict-aliasing]
  
  while(std::getline(sLine, line)){
  
  cc1plus: все предупреждения считаются ошибками

    


Ответы

Ответ 1



Похоже, это бага (точнее регресия) в gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633 Воспроисводится только при включенном -O2/-O3, потому что на этом уровне включается -ftrict-aliasing. Если компилятор менять не получается или уровень оптимизации, то можно просто добавить -fno-strict-aliasing.

четверг, 26 декабря 2019 г.

Путаница с разрядностью MinGW-w64

#c #windows #mingw_w64


Никак не могу разобраться со следующим вопросом.

Я хочу использовать компилятор MinGW-w64, так как он предоставляет более полную поддержку
WinAPI, по сравнению с компилятором MinGW32.

Хочу иметь возможность собирать и для x32, и для x64 платформ. Судя по информации,
которую мне удалось найти, для этого необходимо ставить две версии MinGW-w64.

Я нашел лишь официальный установщик компилятора:     

https://sourceforge.net/projects/mingw-w64/.

Если опустить варианты настройки потоков и исключений, а рассмотреть только целевую
архитектуру, то установщик позволяет установить две версии компилятора:

C:\Program Files (x86)\mingw-w64\i686-8.1.0
C:\Program Files\mingw-w64\x86_64-8.1.0


Методом тыка мне удалось определить, что i686 собирает только для х32, а х86_64 -
только для х64.

Эти обозначения меня окончательно запутывают, ведь обычно через х86 обозначается х32...

Мои вопросы:


При использовании MinGW-w64 для сборки x32 и x64 кода обязательно ставить две версии
компилятора?
Если я правильно понимаю значение термина кросс-компиляция, то получается, что MinGW-w64
не предназначен для перекрестной компиляции, поскольку собирает код только той же разрядности,
которой обладает сам? При использовании этого компилятора невозможно собрать x64 код
из-под x32 системы, потому что x64 версия компилятора не может быть запущена на х32
системе (в общем случае). Однако, можно собирать x32 код в x64 системе путем запуска
x32 версии компилятора благодаря средствам совместимости Windows WoW, но этот способ
не относится к перекрестной компиляции. Все так?

    


Ответы

Ответ 1



Да, надо ставить 2 версии: i686-posix-dwarf - для сборки 32-х битных программ; x86_64-posix-seh - для сборки 64-х битных программ. И да, компилятор для сборки 64-х битных программ, сам по себе 64-х битный, так что из 32-х битной Windows собрать 64-х битный бинарник не получится. Под кросс-компиляцией ещё можно понимать сборку из-под Linux/macOS бинарников для Windows. И Mingw-w64 такое умеет. Но опять же, для 32-х и 64-х битных целей сборки надо ставить отдельные наборы: с префиксом i686-w64-mingw32- для 32-х бит; с префиксом x86_64-w64-mingw32- для 64-х бит.

среда, 24 апреля 2019 г.

Строгий алиасинг в MinGW-w64

При компиляции с MinGW-w64 этого простого кода:
#include #include #include
template void readWithSep(){ std::istringstream sLine; sLine.str("hello"); std::string line; while(std::getline(sLine, line)){ std::cout<int main(){ readWithSep(); }
выдаётся ошибка:
доступ по указателю с приведением типа нарушает правила перекрытия объектов в памяти [-Werror=strict-aliasing] while(std::getline(sLine, line)){
Компилирую так:
i686-w64-mingw32-g++ -std=c++17 -W -Wall -Wextra -pedantic -Werror -O3 file.cpp
Почему возникает эта ошибка и как её исправить? Здесь же вроде никаких преобразований типов не происходит. Странно, что g++ это компилирует без ошибок (с теми же флагами)
Полный вывод компилятора:
file.cpp: В функции «void readWithSep()»: file.cpp:10:35: ошибка: доступ по указателю с приведением типа нарушает правила перекрытия объектов в памяти [-Werror=strict-aliasing] while(std::getline(sLine, line)){ cc1plus: все предупреждения считаются ошибками


Ответ

Похоже, это бага (точнее регресия) в gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633
Воспроисводится только при включенном -O2/-O3, потому что на этом уровне включается -ftrict-aliasing. Если компилятор менять не получается или уровень оптимизации, то можно просто добавить -fno-strict-aliasing