Russian Qt Forum
Март 29, 2024, 08:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Странность с Clang.  (Прочитано 52356 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Октябрь 23, 2019, 13:21 »

Недавно перевёл свои проекты для Android для Clang - теперь им Qt5 собирается. В проекте была ошибка

Код:
void SettingsDlg::isCalendar(bool goodName)
{
    ui->calendarName->setStyleSheet( goodName ? stylegood : stylebad );
}

bool SettingsDlg::isCalendar(QString accountName)
{
    isCalendar( _checkforname(QString) );
}

и вызов выше был:
    isCalendar( oldname );

То есть у второго варианта функции не было возвращаемого значения, хотя функция объявлена как bool (и в .h также). Компилятор выдал предупреждение, хотя по идее должна выдаваться ошибка - возвращаемое значение не определено. Даже QtCreator 5.10 отметил строку замечанием. Но самое странное, что в таком случае... происходило падение при выходе из второго варианта. Заменил возврат bool на void - всё стало нормально. Ну предупреждение вместо ошибки - это ещё ладно, хотя IMHO должна быть серьёзная ошибка. Но падать то от чего? Возврат ведь не использовался. Неопределённое булево значение легло на стек - false или true, не известно. Но его значение вызывающая функция проигнорировала, указатель стека просто отсчитала на 1 больше, и всё.

Пересмотрел ещё раз код - других косяков не видно, работает как вкопанный. То есть, вторичной наведённой ошибки тоже вроде не было. Да и как она может быть, это же не переменная не инициализированная - одно слово на стеке.
Записан

2^7-1 == 127, задумайтесь...
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #1 : Октябрь 23, 2019, 20:01 »

Гурман, посмотрите на то, что генерирует clang:
https://godbolt.org/z/9be4e7

Код
C++ (Qt)
#include <cstdint>
 
int a = 0;
 
void test0()
{
   a = 1;
}
 
bool test()
{
   test0();
}
 
int main()
{
   test();
}
 

Если отключить оптимизацию, то на том месте где должен был быть return clang генерирует инструкцию ud2 (https://www.felixcloutier.com/x86/ud).
Код
ASM
test0():                              # @test0()
       push    rbp
       mov     rbp, rsp
       mov     dword ptr [a], 1
       pop     rbp
       ret
test():                               # @test()
       push    rbp
       mov     rbp, rsp
       call    test0()
       ud2
main:                                   # @main
       push    rbp
       mov     rbp, rsp
       sub     rsp, 16
       call    test()
       xor     ecx, ecx
       mov     byte ptr [rbp - 1], al  # 1-byte Spill
       mov     eax, ecx
       add     rsp, 16
       pop     rbp
       ret
a:
       .long   0                       # 0x0
 

А если включить -O1, то вообще вот так:
Код
ASM
test0():                              # @test0()
       mov     dword ptr [rip + a], 1
       ret
test():                               # @test()
       push    rax
       call    test0()
main:                                   # @main
       push    rax
       call    test()
a:
       .long   0                       # 0x0
 

И что там за test выполняется ему не важно. Улыбающийся
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Октябрь 23, 2019, 23:31 »

 Шокированный

я хотел в код глянуть, но некогда было

однако баг репортом запахло...
Записан

2^7-1 == 127, задумайтесь...
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Октябрь 24, 2019, 06:14 »

однако баг репортом запахло...
По стандарту эта ситуация приводит к UB.
Хотели неопределенности - нате. Улыбающийся

Но по человечески конечно разработчики clang козлы. Не хотите/можете генерировать дальше код - выдайте ошибку, а так и ошибку не выдаем и код не генерим. "Вы либо крестик снимите, либо трусы наденьте". Улыбающийся

gcc тоже варнинг выдает, но хоть код рабочий генерит.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #4 : Октябрь 24, 2019, 10:31 »

однако баг репортом запахло...
По стандарту эта ситуация приводит к UB.
Хотели неопределенности - нате. Улыбающийся
Не.... неопределённость в возвращаемом значении. Но не в алгоритме. По алгоритму функция завершилась, должен быть возврат без определённого значения функции. Обязан быть ret после разбора закрывающей фигурной скобки. Но его нет. Это баг.
« Последнее редактирование: Октябрь 24, 2019, 10:33 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #5 : Октябрь 24, 2019, 11:27 »

Это баг.

Нет, баг у вас Подмигивающий

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Октябрь 24, 2019, 13:23 »


Мой баг только в отсутствии return. Но это совсем не undefined behaviour. Behaviour как раз defined - завершился блок, составляющий тело функции. Значит завершилась функция, и из неё должен быть возврат. Только значение не определено - undefined value но не behaviour. Во всяком случае именно так работали все 6-7 компиляторов, которыми я когда-либо пользовался, начиная с K&R C в RT-11. Если там в статье написано что-то другое - значит чушь написана.
Записан

2^7-1 == 127, задумайтесь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #7 : Октябрь 24, 2019, 13:43 »

Мой баг только в отсутствии return. Но это совсем не undefined behaviour.

Это УБ с точки зрения стандарта. И кланг такой умничка что вставляет трап в месте UB (то, что Old запостил с -O0) чтобы вы могли найти и исправить UB. Гцц даже этого не делает.

Если там в статье написано что-то другое - значит чушь написана.

Не читал, но осуждаю, ясно-понятно.
« Последнее редактирование: Октябрь 24, 2019, 13:46 от Авварон » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Октябрь 24, 2019, 13:51 »

Во всяком случае именно так работали все 6-7 компиляторов, которыми я когда-либо пользовался,
Ну значит 8-й делает не так, и "стоны придавленного дерева" ничего не изменят
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #9 : Октябрь 24, 2019, 14:51 »

Clang был бы умничкой, если бы красную ошибку выдал. Как в случае с return; без значения. Поскольку по сути - это именно он и есть.
Записан

2^7-1 == 127, задумайтесь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #10 : Октябрь 24, 2019, 14:54 »

Clang был бы умничкой, если бы красную ошибку выдал.


-Wall -Wextra -Wpedantic -Werror
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #11 : Октябрь 24, 2019, 15:05 »

-Wall-> -Wmost -> -Wreturn-type

У чувачка банальный -Wall не включен а виноват кланг лол
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #12 : Октябрь 24, 2019, 15:26 »

У чувачка банальный -Wall не включен а виноват кланг лол

Тогда этот "чувачок" в Qt Team работает. Потому как я лично просто стал использовать ровно то, что приехало с Qt 5.12.5, без изменений.
Записан

2^7-1 == 127, задумайтесь...
qate
Супер
******
Offline Offline

Сообщений: 1175


Просмотр профиля
« Ответ #13 : Октябрь 25, 2019, 10:57 »

Это УБ с точки зрения стандарта.

можно ссылку, для ликбеза, на стандарт по УБ для данного случая ?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #14 : Октябрь 25, 2019, 11:48 »

можно ссылку, для ликбеза, на стандарт по УБ для данного случая ?

У меня не открывается на работе, но говорят там такое написано.
Код:
Flowing off the end of a constructor, a destructor, or a function with a cv void return type is equivalent to a return with no operand. Otherwise, flowing off the end of a function other than main (6.6.1) results in undefined behavior.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.114 секунд. Запросов: 22.