C/C++: приведение типов и соответствующие предупреждения компиляторов

Место, где разработчики плагинов могут поделиться своим опытом.
Post Reply
Ariman
Posts: 1351
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 15 times
Been thanked: 50 times
Contact:

C/C++: приведение типов и соответствующие предупреждения компиляторов

Post by Ariman »

skipik wrote: Mon 03 Jul, 2017 21:15при сборке плагина в VS 2015 наблюдаю 3 предупреждени
Тупизна какая-то. Всегда меньшее в большее кастилось без проблем, теперь студия резко разучилась. Но через два каста подряд всё ещё можно. :?
Закомитил фикс. Непонятно почему, но теперь компилятор счастлив.
Last edited by HaRT on Wed 05 Jul, 2017 12:56, edited 1 time in total.
Reason: Обсуждение отделено; добавлена цитата из исходной Темы.
User avatar
DrKnS
Posts: 6114
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 12 times
Been thanked: 426 times

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by DrKnS »

Ariman wrote: Tue 04 Jul, 2017 08:47Тупизна
- void* - это как бы адрес, если туда пихают int, то половину адреса, вероятно, уже где-то сломали/потеряли, промотить молча опасно.
- если ваш int равен, скажем, 0xffffffff, то после каста в void* там будет совсем не 0x00000000ffffffff.
Ariman
Posts: 1351
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 15 times
Been thanked: 50 times
Contact:

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by Ariman »

Не совсем понял. void* это же uint64 (в x64 сборке). Почему явный typecast int -> void* должен отличаться от int -> uint64? Ладно бы на неявное приведение ругалось, это я могу понять.
User avatar
HaRT
Moderator
Posts: 10823
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by HaRT »

Ariman wrote: Tue 04 Jul, 2017 13:36void* это же uint64 (в x64 сборке)
Это не так. Размер у них одинаковый, а смысл разный (тут указатель, а там число).
DrKnS wrote: Tue 04 Jul, 2017 11:02если ваш int равен, скажем, 0xffffffff, то после каста в void* там будет совсем не 0x00000000ffffffff.
У меня в отладчике MSVC 2013 (void*)0xFFFFFFFF даёт как раз 0x00000000ffffffff.
Фар есть инструмент, а не нянька. © 2009 DrKnS
Ariman
Posts: 1351
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 15 times
Been thanked: 50 times
Contact:

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by Ariman »

HaRT wrote: Tue 04 Jul, 2017 14:46 Это не так. Размер у них одинаковый, а смысл разный (тут указатель, а там число).
Указатель это то же самое целое число. Идеологически это может и разные вещи, но физически разницы никакой.
User avatar
HaRT
Moderator
Posts: 10823
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by HaRT »

Ariman wrote: Tue 04 Jul, 2017 15:57Указатель это то же самое целое число.
Вы смешиваете разные уровни абстракции. На архитектуре x86_64 указатель реализуется как адрес, который представляется числом. Своё предупреждение компилятор выдаёт на верхнем из этих уровней, поэтому про нижележащее число он в этот момент знать не хочет (и Вам не советует).
Фар есть инструмент, а не нянька. © 2009 DrKnS
User avatar
DrKnS
Posts: 6114
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 12 times
Been thanked: 426 times

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by DrKnS »

Ariman wrote: Tue 04 Jul, 2017 13:36Почему явный typecast int -> void* должен отличаться от int -> uint64
В x86 (void*)int давало то же самое битовое представление. В x64 - не то же самое.
HaRT wrote: Tue 04 Jul, 2017 14:46У меня в отладчике MSVC 2013 (void*)0xFFFFFFFF даёт как раз 0x00000000ffffffff.
Ну так вы литерал сначала к int приведите.
User avatar
HaRT
Moderator
Posts: 10823
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by HaRT »

DrKnS wrote: Tue 04 Jul, 2017 19:51литерал сначала к int приведите
М-да, я как-то и забыл, что 0xFFFFFFFF в int не укладывается и поэтому имеет тип unsigned int. :oops:
Фар есть инструмент, а не нянька. © 2009 DrKnS
Ariman
Posts: 1351
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 15 times
Been thanked: 50 times
Contact:

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by Ariman »

Всё это конечно хорошо, но:
- компилятор так же само ругается и на приведение unsigned int -> void*,
- в x86 конверсия short в void* даёт такие же эффекты 0xFFFF -> 0xFFFFFFFF, тем не менее компилятор молчит.
Приведение signed в unsigned вообще скользкая тема. И я только за ворнинги при неявном приведении. Но ругня при явном приведении к void* с меньшего размера мне не понятна.
User avatar
DrKnS
Posts: 6114
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 12 times
Been thanked: 426 times

Integrity Checker — работа с хеш-суммами выделенных файлов

Post by DrKnS »

Ariman wrote: Wed 05 Jul, 2017 09:51- в x86 конверсия short в void* даёт такие же эффекты 0xFFFF -> 0xFFFFFFFF, тем не менее компилятор молчит.
Приведение signed в unsigned вообще скользкая тема
В x86 адреса в short, как правило, не паковали.

Скользкая тема - это каст 32-битного типа в адрес, когда в зависимости от знака получаются сильно разные адреса.
Учитывая, что в x86 традиционно не заморачивались и пихали указатели куда попало - я их понимаю. Несмотря на то, что это вполне defined behaviour, лучше явно требовать сначала явного приведения к memsize-типу.
Ariman
Posts: 1351
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 15 times
Been thanked: 50 times
Contact:

C/C++: приведение типов и соответствующие предупреждения компиляторов

Post by Ariman »

DrKnS wrote: Wed 05 Jul, 2017 11:51 Скользкая тема - это каст 32-битного типа в адрес, когда в зависимости от знака получаются сильно разные адреса.
Учитывая, что в x86 традиционно не заморачивались и пихали указатели куда попало - я их понимаю. Несмотря на то, что это вполне defined behaviour, лучше явно требовать сначала явного приведения к memsize-типу.
Приведение к memsize никак не поменяет результат. int->uint64->void* == int->void*. Тогда уже надо требовать, чтобы число unsigned было, там проблем со знаком нет.
User avatar
DrKnS
Posts: 6114
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 12 times
Been thanked: 426 times

C/C++: приведение типов и соответствующие предупреждения компиляторов

Post by DrKnS »

Ariman wrote: Wed 05 Jul, 2017 14:43Приведение к memsize никак не поменяет результат. int->uint64->void* == int->void*
Естественно, он и не должен меняться.
Приводя к memsize ручками вы просто явно декларируете, чего хотите добиться, для себя и для потомков.
Post Reply

Return to “Разработка плагинов”