Почему там предупреждение производительности на указателе броска на bool?

+1 для VisualSVN, являющегося лучше, чем AnkhSVN, попробовав обоих, и +1 для Дополнения FogBugz.

53
задан Community 23 May 2017 в 02:34
поделиться

7 ответов

Это обсуждается в Microsoft Connect ( Какое влияние на производительность оказывает преобразование в bool в C ++? ). Пример, предоставленный Microsoft:

$ cat -n t.cpp && cl -c -W3 -O2 -nologo -Fa t.cpp
1 bool f1 (int i)
2 {
3 return i & 2;
4 }
5
6 bool f2 (int i)
7 {
8 const bool b = i & 2;
9 return b;
10 }
11
12 bool f3 (int i)
13 {
14 const bool b = 0 != (i & 2);
15 return b;
16 }
t.cpp
t.cpp(3) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
t.cpp(8) : warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

И ответ Microsoft (от разработчика, ответственного за предупреждение):

Это предупреждение на удивление полезно, и только вчера обнаружила ошибку в моем коде. Я думаю, что Мартин вырывает «предупреждение о производительности» из контекста.

Дело не в сгенерированном коде, а в том, сигнализировал ли программист о намерении изменить значение с int на bool. За это есть штраф, и у пользователя есть выбор последовательно использовать "int" вместо "bool" (или, что более вероятно, наоборот), чтобы избежать "булевого" кодогенерации. Предупреждение подавлено в третьем случае ниже, потому что он ' s ясно обозначил свое намерение принять переход int-> bool.

Это старое предупреждение, и, возможно, оно уже отжило свое предназначение, но оно ведет себя так, как задумано здесь

Так что в основном разработчик MS, кажется, говорит, что если вы хотите "преобразовать" int в bool , вам лучше сделать это, используя " return this-> parentNode! = 0 " вместо неявного или явное приведение.

Лично мне было бы интересно узнать больше о том, какие ошибки обнаруживает предупреждение. Думаю, это предупреждение не будет иметь большого значения.

s ведет себя так, как задумано здесь

Таким образом, в основном разработчик MS, кажется, говорит, что если вы хотите «преобразовать» int в bool , вам лучше сделать это, используя " return this-> parentNode! = 0 "вместо неявного или явного приведения.

Лично мне было бы интересно узнать больше о том, какие ошибки выявляет предупреждение. Думаю, это предупреждение не будет иметь большого значения.

s ведет себя так, как задумано здесь

Таким образом, в основном разработчик MS, кажется, говорит, что если вы хотите «преобразовать» int в bool , вам лучше сделать это, используя " return this-> parentNode! = 0 "вместо неявного или явного приведения.

Лично мне было бы интересно узнать больше о том, какие ошибки обнаруживает предупреждение. Думаю, это предупреждение не будет иметь большого значения.

46
ответ дан 7 November 2019 в 08:42
поделиться

Тот факт, что приведение к bool не устраняет предупреждение , является намеренным :

Приведение выражения к типу bool не приведет к отключите предупреждение, которое является намеренным.

Я бы порекомендовал подход, который рекомендуется в описании предупреждения C4800 в MSDN:

return this->parentNode != NULL;

это дает понять, что вы возвращаете true if parentNode не является нулевым указателем и ложным , если parentNode является нулевым указателем.

28
ответ дан 7 November 2019 в 08:42
поделиться

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

00000000004005e0 <_Z4testPv>:
bool test(void* adr) {
  4005e0:       48 85 ff                test   %rdi,%rdi
  4005e3:       0f 95 c0                setne  %al
    return adr;
}
  4005f8:       c3                      retq

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

8
ответ дан 7 November 2019 в 08:42
поделиться

Почему это предупреждение о производительности?

Компилятор превращает это:

bool hasParent()
{
  return this->parentNode;
}

в:

bool hasParent()
{
  return this->parentNode != 0;
}

Это занимает примерно один такт больше, чем вы могли бы ожидать, глядя на код. Это незначительная разница в производительности.

Я думаю, что в любом случае лучше указать ! = 0 явно, поскольку это делает код более понятным, а также заглушает предупреждение.

7
ответ дан 7 November 2019 в 08:42
поделиться

Было бы более эффективно написать:

bool hasParent()
{
    return  this->parentNode != NULL;
}
2
ответ дан 7 November 2019 в 08:42
поделиться

На самом деле я думаю, что они будут оптимизировать то же самое, вы также можете попробовать сделать это:

return this->parentNode != 0;
0
ответ дан 7 November 2019 в 08:42
поделиться

Я почти уверен, что это зависит от компилятора

1
ответ дан 7 November 2019 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: