Зачем использовать static_cast <int> (x) вместо (int) x?

Я слышал, что функция static_cast должна быть предпочтительнее преобразования в стиле C или простого преобразования в стиле функции. Это правда? Почему?

Возражаю, ваша честь, спросил и ответил.

Graeme Perrow 19.09.2008 20:36

Я не согласен, этот другой вопрос касался описания различий между приведениями, вводимыми в C++. Этот вопрос касается реальной полезности static_cast, который немного отличается.

Vincent Robert 19.09.2008 20:40

Мы, конечно, могли бы объединить два вопроса, но что нам нужно сохранить из этого потока, так это преимущество использования функций по сравнению с приведением в стиле C, которое в настоящее время упоминается только в однострочном ответе в другом потоке, без голосов .

Tommy Herbert 20.09.2008 12:26

Голосование "за", потому что эта ссылка по-прежнему предоставляет полезную информацию.

Pete 14.08.2009 21:45

Этот вопрос касается «встроенных» типов, таких как int, тогда как этот вопрос касается типов классов. Это кажется достаточно существенной разницей, чтобы заслужить отдельного объяснения.

user153275 20.04.2011 01:21

static_cast на самом деле является оператором, а не функцией.

ThomasMcLeod 25.02.2013 17:47

@ThomasMcLeod Операторы - это особый тип функций (по крайней мере, я так думал)

DarthRubik 26.11.2016 23:33

@DarthRubik, на самом деле вызовы функций - это тип оператора. en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B

ThomasMcLeod 28.11.2016 20:50

@ user153275 хорошо, заголовок посвящен примитивным типам, но вопрос отбрасывает его. И ответы тоже. Я не убежден изменить свой образ жизни. Уверен, что с int x = (int)myfloat; все будет в порядке, и он сделает то, что я от него ожидаю.

Josh C 16.09.2019 21:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
698
9
361 824
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

static_cast, помимо управления указателями на классы, также может использоваться для выполнения преобразований, явно определенных в классах, а также для выполнения стандартных преобразований между фундаментальными типами:

double d = 3.14159265;
int    i = static_cast<int>(d);

Но зачем кому-то писать static_cast<int>(d), если (int)d намного более лаконичен и удобочитаем? (Я имею в виду в случае базовых типов, а не указателей на объекты.)

Todd Lehman 05.08.2015 01:21

@ gd1 - Зачем кому-то ставить согласованность выше удобочитаемости? (на самом деле полусерьезно)

Todd Lehman 13.01.2016 22:35

@ToddLehman: Я, учитывая, что создание исключения для определенных типов только потому, что они для вас особенные, для меня не имеет никакого смысла, и я также не согласен с вашим понятием читабельности. Короче не означает более читабельный, как я вижу из изображения, которое вы разместили в другом комментарии.

gd1 13.01.2016 22:45

static_cast - это четкое и осознанное решение о совершении очень определенного типа преобразования. Следовательно, это добавляет ясности намерениям. Это также очень удобно в качестве маркера для поиска исходных файлов на предмет преобразований при проверке кода, ошибках или обновлении.

Persixty 18.01.2016 13:19

Контрапункт @ToddLehman: Зачем кому-то писать (int)d, когда int{d} намного удобнее для чтения? Конструкторский или функциональный, если у вас (), синтаксис не так быстр, чтобы превратиться в кошмарный лабиринт круглых скобок в сложных выражениях. В этом случае это будет int i{d} вместо int i = (int)d. Гораздо лучше ИМО. Тем не менее, когда мне просто нужно временное значение в выражении, я использую static_cast и никогда не использовал преобразование конструктора, я не думаю. Я использую только (C)casts, когда наспех пишу отладочные cout ...

underscore_d 13.05.2017 02:39

static_cast означает, что вы не можете случайно const_cast или reinterpret_cast, и это хорошо.

Дополнительные (хотя и незначительные) преимущества по сравнению с приведением стиля C заключаются в том, что он выделяется больше (выполнение чего-то потенциально плохого должно выглядеть некрасиво) и более способно работать с grep.

Michael Burr 19.09.2008 20:52

В моей книге grep-способность всегда является плюсом.

Branan 22.09.2008 23:15

Речь идет о том, насколько безопасны типы вы хотите наложить.

Когда вы пишете (bar) foo (что эквивалентно reinterpret_cast<bar> foo, если вы не предоставили оператор преобразования типа), вы говорите компилятору игнорировать безопасность типов и просто делать то, что сказано.

Когда вы пишете static_cast<bar> foo, вы просите компилятор хотя бы проверить, что преобразование типов имеет смысл, а для целочисленных типов - вставить некоторый код преобразования.


РЕДАКТИРОВАТЬ 2014-02-26

Я написал этот ответ более 5 лет назад и ошибся. (См. Комментарии.) Но он все равно получает положительные голоса!

(bar) foo не эквивалентно reinterpret_cast <bar> (foo). Правила для "(TYPE) expr" заключаются в том, что он будет выбирать соответствующее приведение стиля C++ для использования, которое может включать reinterpret_cast.

Richard Corden 19.09.2008 21:43

Хорошая точка зрения. Евро Мичелли дал окончательный ответ на этот вопрос.

Pitarou 20.09.2008 21:03

Также это static_cast<bar>(foo), в скобках. То же для reinterpret_cast<bar>(foo).

L. F. 25.07.2019 04:58

Один практический совет: вы можете легко найти ключевое слово static_cast в исходном коде, если планируете привести проект в порядок.

вы также можете выполнять поиск, используя скобки, например, "(int)", но это хороший ответ и веская причина для использования приведения в стиле C++.

Mike 07.01.2014 15:28

@Mike, который обнаружит ложные срабатывания - объявление функции с одним параметром int.

Nathan Osman 13.09.2016 08:22

Это может дать ложноотрицательные результаты: если вы ищете кодовую базу, в которой вы не единственный автор, вы не найдете приведений в стиле C, которые по некоторым причинам могли быть введены другими.

Ruslan 09.06.2017 09:46

Как это поможет привести в порядок проект?

Bilow 10.10.2017 21:40

Вы не стали бы искать static_cast, потому что это, скорее всего, правильный. Вы хотите отфильтровать static_cast, пока вы ищете reinterpret_cast, const_cast и, возможно, даже dynamic_cast, поскольку они будут указывать на места, которые можно перепроектировать. C-cast смешивает все вместе и не дает вам повода для кастинга.

Dragan 18.05.2020 16:58
Ответ принят как подходящий

Основная причина заключается в том, что классические модели C не делают различий между тем, что мы называем static_cast<>(), reinterpret_cast<>(), const_cast<>() и dynamic_cast<>(). Эти четыре вещи совершенно разные.

static_cast<>() обычно безопасен. В языке есть допустимое преобразование или соответствующий конструктор, который делает это возможным. Единственный раз, когда это немного рискованно, - это когда вы переходите к унаследованному классу; вы должны убедиться, что объект на самом деле является потомком, которого вы утверждаете, с помощью внешних по отношению к языку средств (например, флага в объекте). dynamic_cast<>() безопасен, пока проверяется результат (указатель) или учитывается возможное исключение (ссылка).

С другой стороны, reinterpret_cast<>() (или const_cast<>()) всегда опасен. Вы говорите компилятору: «поверьте мне: я знаю, что это не похоже на foo (похоже, что он не изменяемый), но это так».

Первая проблема заключается в том, что практически невозможно определить, какое из них произойдет при приведении типов в стиле C, не глядя на большие и разрозненные фрагменты кода и не зная всех правил.

Предположим, это:

class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;

CMyBase  *pSomething; // filled somewhere

Теперь эти два компилируются одинаково:

CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked

pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
                                     // Safe; as long as we checked
                                     // but harder to read

Однако давайте посмотрим на этот почти идентичный код:

CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert

pOther = (CMyOtherStuff*)(pSomething);            // No compiler error.
                                                  // Same as reinterpret_cast<>
                                                  // and it's wrong!!!

Как видите, нет простого способа различить две ситуации, не зная много обо всех задействованных классах.

Вторая проблема заключается в том, что приведение типов в стиле C слишком сложно найти. В сложных выражениях может быть очень трудно увидеть приведение типов в стиле C. Практически невозможно написать автоматизированный инструмент, который должен находить приведение типов в стиле C (например, инструмент поиска), без полноценного внешнего интерфейса компилятора C++. С другой стороны, легко найти "static_cast <" или "reinterpret_cast <".

pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
      // No compiler error.
      // but the presence of a reinterpret_cast<> is 
      // like a Siren with Red Flashing Lights in your code.
      // The mere typing of it should cause you to feel VERY uncomfortable.

Это означает, что забросы в стиле C не только более опасны, но и гораздо сложнее найти их все, чтобы убедиться, что они верны.

Вы не должны использовать static_cast для отбрасывания иерархии наследования, а скорее dynamic_cast. Это вернет либо нулевой указатель, либо действительный указатель.

David Thornley 20.01.2010 23:18

@ Дэвид Торнли: Обычно я согласен. Думаю, я указал на предостережения относительно использования static_cast в этой ситуации. dynamic_cast может быть безопаснее, но это не всегда лучший вариант. Иногда вы делаете знать, чтобы указатель указывал на данный подтип, непрозрачным для компилятора средствами, и static_cast работает быстрее. По крайней мере, в некоторых средах dynamic_cast требует дополнительной поддержки компилятора и затрат времени выполнения (включение RTTI), и вы можете не захотеть включать его только для пары проверок, которые вы можете выполнить самостоятельно. RTTI в C++ - лишь одно из возможных решений проблемы.

Euro Micelli 21.01.2010 00:02

Ваше утверждение о приведении C является ложным. Все преобразования C являются преобразованиями значений, примерно сопоставимыми с C++ static_cast. Эквивалент reinterpret_cast в языке C - это *(destination_type *)&, то есть получение адреса объекта, преобразование этого адреса в указатель на другой тип и последующее разыменование. За исключением символьных типов или определенных структурных типов, для которых C определяет поведение этой конструкции, это обычно приводит к неопределенному поведению в C.

R.. GitHub STOP HELPING ICE 04.02.2012 09:56

Ваш точный ответ относится к тексту сообщения. Я искал ответ на заголовок «зачем использовать static_cast <int> (x) вместо (int) x». То есть для типа int (и только int) зачем использовать static_cast<int> вместо (int), поскольку единственное преимущество, по-видимому, заключается в переменных и указателях класса. Попросите вас подробнее рассказать об этом.

chux - Reinstate Monica 15.12.2013 06:15

@chux, для intdynamic_cast не применяется, но все остальные причины остаются в силе. Например: предположим, что v - это параметр функции, объявленный как float, тогда (int)v - это static_cast<int>(v). Но если вы измените параметр на float*, (int)v незаметно станет reinterpret_cast<int>(v), в то время как static_cast<int>(v) будет недопустимым и правильно пойман компилятором.

Euro Micelli 19.12.2013 16:50

@EuroMicelli: Однажды меня укусила описанная вами ситуация. Я преобразовал double* в int, когда считал, что это double. На отладку у меня ушло полдня, и с тех пор я любой ценой избегаю приведений в стиле C.

Siyuan Ren 10.05.2014 13:22

Все ваши примеры предназначены для классов и очень хорошо объясняют, почему программисты должны абсолютно использовать операторы приведения C++. У меня есть проблема: что вы делаете, когда имеете дело с типом пода, таким как int * to void * или void * to int *? В этой ситуации я использую c-приведения или операторы приведения C++? Я мог бы добавить это как вопрос в другой пост. Не уверен, что это здесь.

Zachary Kraus 28.08.2014 01:39

Хотя неясно, должен ли вопрос быть о приведении типов в стиле C++ в целом или об арифметических приведениях в частности, странно видеть, что в этом вопросе в качестве примера используется то, что кажется арифметическим приведением, в то время как принятый ответ полностью игнорирует арифметические преобразования и фокусируется исключительно на иерархических приведениях указателей. (???)

AnT 09.10.2014 06:27

Фактически можно утверждать, что приведение типов в стиле C++ должно быть зарезервировано для приведения иерархических указателей и различных операций взлома, в то время как классические приведения в стиле C следует использовать для арифметических приведений. Это обеспечило бы четкое различие между этими двумя (или тремя) довольно разными мирами слепков. Другими словами, когда вы выполняете арифметическое приведение конкретно к int, на самом деле подходит (int) x, а не static_cast<int>(x).

AnT 09.10.2014 06:29

@AndreyT Существует разница между приведением стиля C и static_cast ... а именно const часть (если мы говорим об арифметическом приведении), которое в C не так актуально, но в C++ компилятор выполняет гораздо больше. .. И может привести к неопределенному поведению, если вы не будете осторожны.

rubenvb 09.10.2014 11:55

@AndreyT Возможно, вы правы. Однако использование приведения в стиле C++ добавляет компилятору обнаружение случаев, когда программист случайно использует неправильное приведение (например, использовался static_cast<>, но требуется reinterpret_cast<>). Нет реальной причины отказываться от этого. И нет, это включает приведение к (int), потому что вы не хотите, чтобы компилятор молча применял reinterpret_cast<int> после того, как вы реорганизовали некоторый код).

sehe 09.10.2014 11:57

@rubenvb: Я не понимаю, о чем вы говорите. Вы, должно быть, что-то путаете. const вообще не играет роли в арифметических приведениях. Вопрос const относится только к приведению указателя / ссылки, которое не является арифметическим. Итак, какой смысл вы пытаетесь подчеркнуть, упомянув здесь const, и как это связано с тем, что я сказал выше, мне не ясно.

AnT 09.10.2014 19:03

@sehe: Если рефакторинг настолько серьезен, что может превратить арифметическое приведение в приведение по-новому, то в любом случае потребуется тщательная проверка кода, которая будет включать в себя гораздо больше, чем обнаружение и исправление таких приведений (при условии, что существует даже заслуживающий доверия вариант использования).

AnT 09.10.2014 19:10

Влияние дополнительного образа мыслей, обеспечиваемого static_cast в таких случаях, на мой взгляд, несущественно по сравнению с положительным влиянием на читаемость кода, обеспечиваемым более элегантными арифметическими приведениями и визуальным разделением арифметических приведений от иерархических / хакерских. Я считаю, что последний эффект значительно более ценен. Поэтому я придерживаюсь приведений в стиле C для арифметических преобразований: вознаграждение намного превышает риск.

AnT 09.10.2014 19:10

@AndreyT, и дело в том, что тщательная проверка кода может легко упустить эти вещи именно потому, что им не хватает многословности - намерение не заявлено однозначно. Это приведет к ошибке.

sehe 09.10.2014 19:14

@sehe: О, когда рефакторинг настолько радикален, тщательная проверка кода может упустить многое, среди которых этот конкретный вопрос вообще не играет большой роли. Возвращаясь к теме: другими словами, даже при том, что они хотели разделить разные типы приведений, они не пошли достаточно далеко. static_cast все еще переполнен. Мне нужен специальный состав для арифметических преобразований. И мне это так необходимо, что я рискну использовать приведение в стиле C для арифметических преобразований только для того, чтобы мои арифметические преобразования выглядели иначе.

AnT 09.10.2014 19:14

@AndreyT Ничто не мешает вам делать что-то вроде integer_cast<>, который делает все, что вам нужно (я думаю, что для этого может быть что-то в Boost Integer). Подобные вещи могут уже существовать (со специализированными библиотеками, такими как SafeInt)

sehe 09.10.2014 19:16

you must make sure that the object is a actually the descendant that you claim it is, by means external to the language (like a flag in the object). Я не согласен (кроме того факта, что член в объекте не является «внешним по отношению к языку»): если программа правильно спроектирована, вполне возможно узнать, что объект имеет правильный тип, и пометить это тратит впустую пространство. Просто убедитесь, что вы знаете свои экземпляры, если вы используете static_cast, и убедитесь, что assert() на эквивалентном dynamic_cast при запуске отладочных сборок.

underscore_d 13.05.2017 02:30

@jterm Что? Нет ничего небезопасного, если экземпляр, приведенный к "дочернему" является, является дочерним, а делает имеет те члены, о которых знает хороший программист. (И, в идеале, assert( dynamic_cast ... ) в отладочных сборках)

underscore_d 13.05.2017 02:30

@underscore_d, под «внешним по отношению к языку» я имею в виду, что язык не определяет значение любого такого флага (компилятор не знает, что он означает, и не может его проверить). «Я знаю, что делаю», как вы указываете, конечно, совершенно верно и может спасти вас от использования флага в зависимости от программы. Это тоже «внешнее по отношению к языку» :-).

Euro Micelli 13.05.2017 03:24

«нет различия между тем, что мы называем static_cast <> (), reinterpret_cast <> (), const_cast <> () и dynamic_cast <>» «различие» состоит в том, что не существует такой вещи, как dynamic_cast<>, выполненный с помощью приведения в стиле C или синтаксиса приведения в функциональном стиле.

curiousguy 28.05.2018 05:10

dynamic_cast<>() не имеет отношения к приведению в стиле c.

Amos 21.06.2018 10:26

Другая ситуация, когда static_cast может быть рискованным, заключается в том, что static_cast позволяет преобразовать любой тип указателя в void* и void* в любой тип указателя, что позволит вам, например, преобразовать char* в void*, а затем в int*.

Donald Duck 11.07.2018 06:08

Хорошей практикой является использование ключевого слова, определенного макросом, для поиска приведений в c-файлах.

mitghi 09.08.2018 16:06
«const_cast<>() [...] всегда опасен» - not so, only if used to удалятьconst or volatile. const_cast<T const volatile&>(t) is always safe, and const_cast<T const&>(t) is safe provided t is not volatile.
Eric 07.10.2019 10:28

@DonaldDuck "что позволит вам, например, использовать" Если вы имеете дело с void* и считаете, что он исходит от T*, но не совсем уверены, решения нет. Никакой синтаксис приведения не поможет, поскольку это принципиально проблема дизайна.

curiousguy 03.11.2019 02:50
Путь better advice than what I learned from which was just blindly calling things "evil" instead of explaining their uses and their pitfalls. +10 even though I can only give +1
The_Sympathizer 05.06.2020 08:10

Вопрос больше, чем просто использование приведений в стиле static_cast или C, потому что при использовании приведений в стиле C происходят разные вещи. Операторы приведения C++ призваны сделать эти операции более явными.

На поверхности приведения в стиле static_cast и C выглядят одинаково, например, при приведении одного значения к другому:

int i;
double d = (double)i;                  //C-style cast
double d2 = static_cast<double>( i );  //C++ cast

Оба они приводят целочисленное значение к двойному. Однако при работе с указателями все усложняется. Некоторые примеры:

class A {};
class B : public A {};

A* a = new B;
B* b = (B*)a;                                  //(1) what is this supposed to do?

char* c = (char*)new int( 5 );                 //(2) that weird?
char* c1 = static_cast<char*>( new int( 5 ) ); //(3) compile time error

В этом примере (1) возможно, все в порядке, потому что объект, на который указывает A, на самом деле является экземпляром B. Но что, если вы не знаете в этой точке кода, на что на самом деле указывает a? (2) может быть совершенно законным (вы хотите посмотреть только один байт целого числа), но это также может быть ошибкой, и в этом случае ошибка будет приятной, как (3). Операторы приведения C++ предназначены для выявления этих проблем в коде, по возможности предоставляя ошибки времени компиляции или выполнения.

Итак, для строгого «приведения значений» вы можете использовать static_cast. Если вы хотите полиморфное приведение указателей во время выполнения, используйте dynamic_cast. Если вы действительно хотите забыть о типах, вы можете использовать reintrepret_cast. А чтобы просто выбросить const из окна, есть const_cast.

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

Приведения стиля C легко пропустить в блоке кода. Приведение стилей C++ - это не только лучшая практика; они предлагают гораздо большую гибкость.

reinterpret_cast позволяет преобразовывать целые типы в указатели, однако может быть небезопасным при неправильном использовании.

static_cast предлагает хорошее преобразование для числовых типов, например. от перечислений до целых чисел или целых чисел в числа с плавающей запятой или любых типов данных, в типе которых вы уверены. Он не выполняет никаких проверок времени выполнения.

С другой стороны, dynamic_cast будет выполнять эти проверки, отмечая любые неоднозначные назначения или преобразования. Он работает только с указателями и ссылками и вызывает накладные расходы.

Есть несколько других, но это основные из них, с которыми вы столкнетесь.

  1. Позволяет легко находить слепки в ваш код с использованием grep или аналогичного инструменты.
  2. Делает это явным, какой актеров, которые вы делаете, и увлекательные помощь компилятора в обеспечении его соблюдения. Если вы хотите только отбросить const-ness, тогда вы можете использовать const_cast, что не позволит вам делать другие типы преобразований.
  3. Броски по своей сути уродливы - вы, как программист отвергает то, как компилятор обычно обрабатывает ваш код. Вы говорите компилятор: «Я знаю лучше тебя». В таком случае это имеет смысл что выполнение гипса должно быть умеренно болезненная вещь, и что они должны торчать в твоем код, поскольку они являются вероятным источником проблем.

См. Эффективный C++ Введение

Я полностью согласен с этим для классов, но имеет ли смысл использование типов C++ для типов POD?

Zachary Kraus 28.08.2014 01:44

Я думаю так. Все 3 причины применимы к POD, и полезно иметь только одно правило, а не отдельные правила для классов и POD.

JohnMcG 12.09.2014 23:12

Интересно, что в будущем коде для типов POD мне, возможно, придется изменить то, как я выполняю приведение типов.

Zachary Kraus 14.09.2014 07:35

In short:

  1. static_cast<>() gives you a compile time checking ability, C-Style cast doesn't.
  2. static_cast<>() can be spotted easily anywhere inside a C++ source code; in contrast, C_Style cast is harder to spot.
  3. Intentions are conveyed much better using C++ casts.

More Explanation:

The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.

*p = 5; // run-time error: stack corruption

In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.

int *q = static_cast<int*>(&c); // compile-time error

Подробнее на:
В чем разница между static_cast <> и кастингом в стиле C
и
Обычное приведение против static_cast против dynamic_cast

Я не согласен с тем, что static_cast<>() более читабелен. Я имею в виду, что это иногда, но в большинстве случаев - особенно для базовых целочисленных типов - это просто ужасно и излишне многословно. Например: это функция, которая меняет местами байты 32-битного слова. Было бы почти невозможно прочитать, используя приведение static_cast<uint##>(), но довольно легко понять, используя приведение (uint##). Изображение кода:imgur.com/NoHbGve

Todd Lehman 05.08.2015 01:17

@ToddLehman: Спасибо, но я тоже не сказал always. (но в большинстве случаев да) Конечно, бывают случаи, когда приведение стиля c более читабельно. Это одна из причин, по которой кастинг стиля c все еще жив и работает в C++ imho. :) Кстати, это был очень хороший пример

Rika 23.05.2016 13:06

Код @ToddLehman в этом изображении использует два связанных приведения ((uint32_t)(uint8_t)) для достижения того, что байты, помимо самого низкого, сбрасываются. Для этого есть побитовое и (0xFF &). Использование приведений скрывает намерение.

Öö Tiib 20.08.2018 16:02

Другие вопросы по теме