VS2013 C++11, && последовательность
Раньше (уже не помню почему) я думал что последовательность вычислений операндов в логическом выражении слева на право, причем правая часть вообще может быть не вычислена если результат и так ясен из левой части.
Напр.
if (AA && BB){...} // BB не нужно вычислять если AA == false
Но сегодня неожиданно наткнулся что я не прав!
В оригинальном коде в качестве AA была функция возвращающая bool, а в качестве BB - просто сравнение.
Для своих дебаг-целей я заменил возвращаемое значение функции с bool на класс, который однако имеет операторы члены приведения к bool и &&.
В этом случае оказалось что BB вычисляется первым! А в этом старом коде последовательность важна.
Разве последовательность не стандартизирована?
если поточнее то подобный код:
bool GetPtr(void **p)
{
*p = (void*)1;
return true;
}
void main()
{
void* p = NULL;
if (GetPtr(&p) && p != NULL)
{
....сюда не войдёт если GetPtr возвращает класс, т.к. в этом случае p != NULL будет вычислено раньше вызова GetPtr.
однако войдёт если GetPtr возвращает bool.
}
}
да вроде ничего не менялось как был && short-circuit evaluation так и осталось.
вы никаких многопоточных прибамбасов не подключили? что бы типа проц не простаивал, а паралельно уже второе условие проверял?
EDIT: о, вот что еще, это прям ваш случай!
http://en.cppreference.com/w/cpp/language/oper...
Restrictions
- The operators
::
(scope resolution),.
(member access),.*
(member access through pointer to member), and?:
(ternary conditional) cannot be overloaded. - New operators such as
**
,<>
, or&|
cannot be created. - The overloads of operators
&&
and||
lose short-circuit evaluation. - The overload of operator
->
must either return a raw pointer or return an object (by reference or by value), for which operator->
is in turn overloaded. - It is not possible to change the precedence, grouping, or number of operands of operators.
Search & Replace = 10 минут...
это только со стороны кажется что так просто. Поиск конечно сработает, но только самой функции, но Замена - придётся ручками. Т.к. функция имеет несколько параметров и они в каждом случае имеют другие имена.
1. Если в выражении AA && BB AA вернуло false, то по умолчанию BB вычислено не будет, хотя как указал pavel-hh это можно переопределить, (если очень хочется) написав свой собственный operator&&.
2. А как Вы определили operator&& в Вашем классе?
3. Лучше всего поместите целую законченную программу, которая компилируется. Иначе всё слишком абстрактно.
PS Сомневаюсь, что кто-то сознательно напортачил.
Вот погладел сколько раз встречается: почти 2500 раз.
так что ручками если вмешиваться - на долго.
Оставлю так.
Просто я хотел возвращение класса оставить в Дебаг версии. Но т.к. поведение меняется, то нельзя даже для Дебага.
Но свою службу класс отслужил: при компилировании он показал (выдал ошибки) все места где возвращаемый bool прислваивался или сравнивался с HRESULT.
На одну такую лажу я наткнулся и решил проверить всю программу. Нашел много тупого кода типа if (FAILED(GetPtr())) тоже и с SUCCEEDED. Который ввиду булевского возврата означает if(false) или if(true).
эти макросы такие, если кто не знаком:
#define FAILED(h) ((h) < 0)
#define SUCCEDED(h) ((h) >= 0)
Вот погладел сколько раз встречается: почти 2500 раз.так что ручками если вмешиваться - на долго.Оставлю так.
под линуксом или в cygwin можно было бы и 5000 замен с разными параметрами повести
а что там за сервис такой?
я сам подумывал над использованием регулярных выражений, но - не силён в них, особенно в Замене (поиском пользуюсь).
Кто знает, можно ли там одним кликом найти и заменить типа того:
AAA xxx BBB ---> CCC xxx DDD
где xxx - постоянно разное, а AAA.BBB,CCC,DDD всегда одинаковы.
?
EDIT:
понял сам - ищем AAA(.*)BBB, заменяем на CCC$1DDD
AAA(.*)BBB, заменяем на CCC$1DDD
Аккуратнее. Простая * обычно "жадный" квантор. Т.е. заберет максимум того, что сможет.
Из AAAxxxxxxBBByyyyyBBB заберет xxxxxxBBByyyyy
Если у вас такого не встречается, тогда не страшно. А так - меняйте на "не жадный". Как оно в sed-е я уже и не помню. Что-то вроде *? вместо *