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

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

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

Post by Ariman » Tue 04 Jul, 2017 08:47

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: 4609
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 121 times
Contact:

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

Post by DrKnS » Tue 04 Jul, 2017 11:02

Ariman wrote:
Tue 04 Jul, 2017 08:47
Тупизна
- void* - это как бы адрес, если туда пихают int, то половину адреса, вероятно, уже где-то сломали/потеряли, промотить молча опасно.
- если ваш int равен, скажем, 0xffffffff, то после каста в void* там будет совсем не 0x00000000ffffffff.

Ariman
Posts: 1153
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 10 times
Been thanked: 23 times
Contact:

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

Post by Ariman » Tue 04 Jul, 2017 13:36

Не совсем понял. void* это же uint64 (в x64 сборке). Почему явный typecast int -> void* должен отличаться от int -> uint64? Ладно бы на неявное приведение ругалось, это я могу понять.

User avatar
HaRT
Moderator
Posts: 8074
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 100 times

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

Post by HaRT » Tue 04 Jul, 2017 14:46

Ariman wrote:
Tue 04 Jul, 2017 13:36
void* это же uint64 (в x64 сборке)
Это не так. Размер у них одинаковый, а смысл разный (тут указатель, а там число).
DrKnS wrote:
Tue 04 Jul, 2017 11:02
если ваш int равен, скажем, 0xffffffff, то после каста в void* там будет совсем не 0x00000000ffffffff.
У меня в отладчике MSVC 2013 (void*)0xFFFFFFFF даёт как раз 0x00000000ffffffff.
Фар есть инструмент, а не нянька. © 2009 DrKnS

Ariman
Posts: 1153
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 10 times
Been thanked: 23 times
Contact:

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

Post by Ariman » Tue 04 Jul, 2017 15:57

HaRT wrote:
Tue 04 Jul, 2017 14:46
Это не так. Размер у них одинаковый, а смысл разный (тут указатель, а там число).
Указатель это то же самое целое число. Идеологически это может и разные вещи, но физически разницы никакой.

User avatar
HaRT
Moderator
Posts: 8074
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 100 times

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

Post by HaRT » Tue 04 Jul, 2017 16:07

Ariman wrote:
Tue 04 Jul, 2017 15:57
Указатель это то же самое целое число.
Вы смешиваете разные уровни абстракции. На архитектуре x86_64 указатель реализуется как адрес, который представляется числом. Своё предупреждение компилятор выдаёт на верхнем из этих уровней, поэтому про нижележащее число он в этот момент знать не хочет (и Вам не советует).
Фар есть инструмент, а не нянька. © 2009 DrKnS

User avatar
DrKnS
Posts: 4609
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 121 times
Contact:

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

Post by DrKnS » Tue 04 Jul, 2017 19:51

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: 8074
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 67 times
Been thanked: 100 times

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

Post by HaRT » Tue 04 Jul, 2017 20:29

DrKnS wrote:
Tue 04 Jul, 2017 19:51
литерал сначала к int приведите
М-да, я как-то и забыл, что 0xFFFFFFFF в int не укладывается и поэтому имеет тип unsigned int. :oops:
Фар есть инструмент, а не нянька. © 2009 DrKnS

Ariman
Posts: 1153
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 10 times
Been thanked: 23 times
Contact:

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

Post by Ariman » Wed 05 Jul, 2017 09:51

Всё это конечно хорошо, но:
- компилятор так же само ругается и на приведение unsigned int -> void*,
- в x86 конверсия short в void* даёт такие же эффекты 0xFFFF -> 0xFFFFFFFF, тем не менее компилятор молчит.
Приведение signed в unsigned вообще скользкая тема. И я только за ворнинги при неявном приведении. Но ругня при явном приведении к void* с меньшего размера мне не понятна.

User avatar
DrKnS
Posts: 4609
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 121 times
Contact:

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

Post by DrKnS » Wed 05 Jul, 2017 11:51

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

Скользкая тема - это каст 32-битного типа в адрес, когда в зависимости от знака получаются сильно разные адреса.
Учитывая, что в x86 традиционно не заморачивались и пихали указатели куда попало - я их понимаю. Несмотря на то, что это вполне defined behaviour, лучше явно требовать сначала явного приведения к memsize-типу.

Ariman
Posts: 1153
Joined: Fri 30 Nov, 2007 15:32
Location: Крым
Has thanked: 10 times
Been thanked: 23 times
Contact:

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

Post by Ariman » Wed 05 Jul, 2017 14:43

DrKnS wrote:
Wed 05 Jul, 2017 11:51
Скользкая тема - это каст 32-битного типа в адрес, когда в зависимости от знака получаются сильно разные адреса.
Учитывая, что в x86 традиционно не заморачивались и пихали указатели куда попало - я их понимаю. Несмотря на то, что это вполне defined behaviour, лучше явно требовать сначала явного приведения к memsize-типу.
Приведение к memsize никак не поменяет результат. int->uint64->void* == int->void*. Тогда уже надо требовать, чтобы число unsigned было, там проблем со знаком нет.

User avatar
DrKnS
Posts: 4609
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 4 times
Been thanked: 121 times
Contact:

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

Post by DrKnS » Wed 05 Jul, 2017 15:17

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

Post Reply

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