Оч редко, но вот таки снова вылетел
Заметки себе - это с крокодилом и та и другая катка, предположительно все-таки из-за повышения уровня абилы у мёртвого, наверное, там проверка недостаточно правильная

Принятый ответ

.Q..I.VW.bi...|$ == изменение абилки у мертвого юнита
в логе четко видно ид X82A
0
21
7 лет назад
0
Не, ну бред какой-то
ну вот у него проверка перед заданием лвла дамми девотион ауры в спеллбуке
я грешу, что фатал может вылететь от повышения лвла абилы у мёртвой боевой единицы
if (u5 == null) then

call PauseTimer (t)
call DestroyTimer (t)
call FlushChildHashtable (udg_Hash, GetHandleId(t))

else

//ЕСЛИ БРОНЯ БОЛЬШЕ ДОПУСТИМОГО ЛВЛА - СНИЗИТЬ НОМЕР
if number > GetUnitAbilityLevelSwapped('A28T',u5) * 22 then
set number = GetUnitAbilityLevelSwapped('A28T',u5) * 22
endif
if number > 99 then
set number = 99
endif
//ЕСЛИ БРОНЯ БОЛЬШЕ ДОПУСТИМОГО ЛВЛА - СНИЗИТЬ НОМЕР - ЗАКРЫТО.

//ДОБАВКА И ДИЗЕЙБЛ СПЕЛЛБУКОВ, ЗАДАНИЕ НУЖНОГО УРОВНЯ СПОСОБНОСТИ, ТОЛЬКО ЕСЛИ ЖИВ!!!
if IsUnitAliveBJ(u5) == true and GetUnitState(u5,UNIT_STATE_LIFE)>1 and IsUnitDeadBJ(u5) == false then
call UnitAddAbility(u5,'A28W')
call SetPlayerAbilityAvailableBJ( false, 'A28W', GetOwningPlayer(u5) )
call UnitMakeAbilityPermanent(u5,true,'A28W')
call UnitMakeAbilityPermanent(u5,true,'A28X')
call SetUnitAbilityLevelSwapped('A28X',u5,R2I(number))
endif
//ДОБАВКА И ДИЗЕЙБЛ СПЕЛЛБУКОВ - ЗАКРЫТО.

endif
По-моему, проверка даже излишне осторожная немножко, т. к. если он будет живой с хп 1, то не получит ауры брони и повышения ее уровня (но вероятность этого < 0.1% по очевидной причине, а вероятность того, что он через секунду либо не умрёт, либо не отрегает хп, < 0.001%).
Тогда какого панциря фатал? Это не ульта, ни в той ни в другой катке крокодил до 8 уровня не докачивался. Остаются кушка - но это тупо АоЕ дамаг с накидыванием и сразу убиранием абилы ауры дамага... и... ешка, ну там увеличивается броня на сотые доли через мемхак, но без умножения, просто через мемхак плюсуются сотые доли брони, неужели что-то в ешке?
^^^^
Короче, выше это все лирика, просто интересно по логу причины фатала узнать.
0
32
7 лет назад
Отредактирован quq_CCCP
0
Чет ваще ниче непонятно, аж 3 проверки, когда достаточно 1
GetUnitState( unit, UNIT_STATE_LIFE ) > 0.405
Да и проверять сдох ли юнит нужно в начале, а не сначала считать левелы а потом проверять жив ли он.
Есть функция GetUnitAbilityLevel - нафиг юзать бж огрызки?
так же есть IMinBJ если вам так нравится, set number = IMinBJ( 99, number )
Ты уверен что фаталит именно этот код?
0
21
7 лет назад
0
quq_CCCP, в обеих катках с фаталом был крокодил, так что 90%, что из-за крокодила
а у крокодила это самая подозрительная абила
но это что-то очень-очень редкое, в каком бы коде ни было, потому что когда был словлен первый фатал с крокодилом, мной было поставлено 6 ботов-крокодилов и они 5 минут рубились без фатала, и вообще минимум 80% каток с крокодилами проходило без фатала, а точнее, все, кроме двух, вторая только что была
проверок до фига поставлено именно от греха подальше на всякий случай
замечания учту
Вот вся функция целиком на вторую абилу, в которой сильнее всего сомневаюсь:
смотреть сюда
function SkinForFriendsRefresh takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
local timer t = GetExpiredTimer()
local unit u5=LoadUnitHandle(udg_Hash,GetHandleId(t),2)
local real number = GetUnitArmor(u5)
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
if (u5 == null) then
call PauseTimer (t)
call DestroyTimer (t)
call FlushChildHashtable (udg_Hash, GetHandleId(t))
else
ЕСЛИ БРОНЯ БОЛЬШЕ ДОПУСТИМОГО ЛВЛА - СНИЗИТЬ НОМЕР
if number > GetUnitAbilityLevelSwapped('A28T',u5) * 22 then
set number = GetUnitAbilityLevelSwapped('A28T',u5) * 22
endif
if number > 99 then
set number = 99
endif
ЕСЛИ БРОНЯ БОЛЬШЕ ДОПУСТИМОГО ЛВЛА - СНИЗИТЬ НОМЕР - ЗАКРЫТО.
ДОБАВКА И ДИЗЕЙБЛ СПЕЛЛБУКОВ, ЗАДАНИЕ НУЖНОГО УРОВНЯ СПОСОБНОСТИ, ТОЛЬКО ЕСЛИ ЖИВ!!!
if IsUnitAliveBJ(u5) == true and GetUnitState(u5,UNIT_STATE_LIFE)>1 and IsUnitDeadBJ(u5) == false then
call UnitAddAbility(u5,'A28W')
call SetPlayerAbilityAvailableBJ( false, 'A28W', GetOwningPlayer(u5) )
call UnitMakeAbilityPermanent(u5,true,'A28W')
call UnitMakeAbilityPermanent(u5,true,'A28X')
call SetUnitAbilityLevelSwapped('A28X',u5,R2I(number))
endif
ДОБАВКА И ДИЗЕЙБЛ СПЕЛЛБУКОВ - ЗАКРЫТО.
endif
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
set t = null
set u5 = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
Может, ещё гетюнитармор не надо в начале считать при объявлении переменных? Она не мемхачная, а старая с хайва и там селфдамаг... может, там если юнита вдруг оказалось, что нет, получается ноль и из-за этого трындец где-то дальше... попробую мб заменить на мемхачную
Я просто пока размышляю
Я по логу хочу причину фатала услышать
У меня два основных предположения - если от вылета из-за повышения уровня абилы у мёртвой боевой единицы, то это точно эта абила (вторая). Если от записи чего-то в память, то это третья.
Третья вот, если кому не лениво ещё и её смотреть:
смотреть сюда
function BlessingOfTheNileAttack takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6
local timer t = CreateTimer()
local unit u5 = GetAttacker()
local unit u6 = GetAttackedUnitBJ()
local integer level = R2I(GetUnitAbilityLevelSwapped('A28U',u5))
local integer i = 0
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
if (u5 !=null) then
if ( GetUnitAbilityLevelSwapped('A28U', u5) > 0 ) and ( GetUnitAbilityLevelSwapped('A290', u5) > 0 ) then
Удаление маркера с атаковавшего
call UnitRemoveAbility(u5,'A290')
Удаление маркера с атаковавшего - закрыто.
ДОБАВКА БРОНИ
call SetUnitBaseArmor(u5, GetUnitBaseArmor(u5) + 0.01 * I2R(level))
ДОБАВКА БРОНИ - ЗАКРЫТО.
call SaveUnitHandle(udg_Hash,GetHandleId(t),2,u5)
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,u6)
call SaveInteger(udg_Hash,GetHandleId(t),3,i)
call SaveInteger(udg_Hash,GetHandleId(t),4,level)
call TimerStart(t,0.25,true,function BlessingOfTheNileAttack2)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6
set t = null
set u5 = null
set u6 = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
function BlessingOfTheNileRefresh takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6, p, heroadded, heroaction, enemies
local timer t = GetExpiredTimer()
local unit u5=LoadUnitHandle(udg_Hash,GetHandleId(t),2)
local unit u6
local location p = GetUnitLoc(u5)
local trigger heroadded=LoadTriggerHandle(udg_Hash,GetHandleId(t),20)
local triggeraction heroaction=LoadTriggerActionHandle(udg_Hash,GetHandleId(t),21)
local group enemies=CreateGroup()
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local integer i = LoadInteger(udg_Hash,GetHandleId(t),3)
set i = i+1
call SaveInteger (udg_Hash,GetHandleId(t),3,i)
Если героя нет, то разрушить таймер, чтобы не крутился и не жрал ресурсы.
if (u5 == null) then
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash,GetHandleId(t))
call TriggerRemoveAction(heroadded,heroaction)
call DestroyTrigger(heroadded)
else
call TriggerRemoveAction(heroadded,heroaction)
call DestroyTrigger(heroadded)
set heroadded=CreateTrigger()
set heroaction = TriggerAddAction(heroadded,function BlessingOfTheNileAttack)
set enemies = GetUnitsInRangeOfLocAll(800.00, p)

loop
set u6=FirstOfGroup(enemies)
exitwhen u6==null
call GroupRemoveUnit(enemies,u6)
if ( GetUnitAbilityLevelSwapped('Avul', u6) != 1 ) and ( IsUnitAliveBJ(u6) == true ) and ( IsUnitEnemy(u6,GetOwningPlayer(u5))==true ) then
call TriggerRegisterUnitEvent(heroadded, u6, EVENT_UNIT_ATTACKED)
else
endif
endloop
call DestroyGroup (enemies)
call SaveTriggerHandle(udg_Hash,GetHandleId(t),20,heroadded)
call SaveTriggerActionHandle(udg_Hash,GetHandleId(t),21,heroaction)
endif

call RemoveLocation (p)
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6, p, heroadded, heroaction, enemies
set t = null
set u5 = null
set u6 = null
set p = null
set heroadded = null
set heroaction = null
set enemies = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
Кушка простейшая, там фатала в принципе не должно быть, сейчас была перепроверена - ничего подозрительного не вижу...
2
16
7 лет назад
2
.Q..I.VW.bi...|$ == изменение абилки у мертвого юнита
в логе четко видно ид X82A
Принятый ответ
0
21
7 лет назад
0
Понятно...
Ну вот он код в первом сообщении, вот A28X абила... Какого панциря при проверке аж тремя функциями
if IsUnitAliveBJ(u5) == true and GetUnitState(u5,UNIT_STATE_LIFE)>1 and IsUnitDeadBJ(u5) == false
игра умудряется его в редком случае видеть НЕ мёртвым?!
Она тут его живого-то с 1 хп за мёртвого должна считать, а получается, что и мёртвого всё-таки иногда (хотя и КРАЙНЕ редко) живым видит.
0
30
7 лет назад
Отредактирован Clamp
0
проверка даже излишне осторожная немножко
Прямо поэзия в этих строках есть какая-то. А вообще, "излишне" и "немножко" это взаимоисключающие понятия.
IsUnitAliveBJ(u5) == true and GetUnitState(u5,UNIT_STATE_LIFE)>1 and IsUnitDeadBJ(u5) == false
Три абсолютно идентичные по сути проверки (слегка разные по быстродействию), достаточно одной.

Может, ещё гетюнитармор не надо в начале считать при объявлении переменных? Она не мемхачная, а старая с хайва и там селфдамаг... может, там если юнита вдруг оказалось, что нет, получается ноль и из-за этого трындец где-то дальше... попробую мб заменить на мемхачную
0
21
7 лет назад
0
Clamp, вот с одной точно жопа будет, потому что уже есть опыт, IsUnitAlive и IsUnitDead точно косые какие-то.
Потому что у меня есть другой герой, Гидралиск, который вселяется в крипа, хайдится и типа входит внутрь него до смерти крипа (можно эту смерть вручную сделать через добавляемую крипу абилку, типа разорвать его изнутри и вылезти).
Там стояла одна проверка.
Так вот в большинстве случаев все было ок, но бывало, что, когда крип умирал, Гидралиск не анхайдился до его разложения (а это полная жопа).
Вот ща там проверка типа такой тройной по-моему и вроде тьфу-тьфу все норм.
Проверка именно поэтому такая хардкорная стоит и здесь, и вот даже её оказалось недостаточно.
Короче, не знаю, в крайнем случае поменяю единицу на цифру чуть побольше (правда, чем больше будет цифра - тем больше уже будет фактическая погрешность в действии способности, но вплоть до 100 хп это будет не сильно страшно), тут трудности в том, что фатал действительно очень редко, так что сложно будет понять, исправлен он окончательно или нет.
/
БД на броню в 2017 и во времена мемхака... как раз с GetUnitArmor от него отказ и произошёл, спасибо, если все через бд делать, так и варкрафт не очень нужен
0
30
7 лет назад
0

Какого панциря
Сначала все возможные проверки, потом все зависящие от них действия, не наоборот. Кстати:
call UnitAddAbility(u5,'A28W')
call SetPlayerAbilityAvailableBJ( false, 'A28W', GetOwningPlayer(u5) )
call UnitMakeAbilityPermanent(u5,true,'A28W')
call UnitMakeAbilityPermanent(u5,true,'A28X')
call SetUnitAbilityLevelSwapped('A28X',u5,R2I(number))
Весь этот мусор можно вынести в отдельную функцию, намного проще будет дебажить.
И научись, пожалуйста, пользоваться таким построением при постинге:
((код
// тут код
))
0
21
7 лет назад
0
Clamp, "Сначала все возможные проверки, потом все зависящие от них действия, не наоборот" - а у меня как?
Про функцию - справедливо, ну много чего можно посжимать в функции, да, но это дофига перелопачивать, хотя себя оправдает, ну это ок, но немного другой вопрос.
0
30
7 лет назад
Отредактирован Clamp
0
БД на броню в 2017 и во времена мемхака...
"Портируемость" явно не входит в список знакомых тебе понятий. Советую проникнуться ею достаточно глубоко, чтобы не использовать тот или иной недокументированный функционал (это вообще, не только про вц), так как он имеет свойство переставать существовать после багфиксов.

Про "дополнительные" проверки:
//===========================================================================
function IsUnitDeadBJ takes unit whichUnit returns boolean
    return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
endfunction

//===========================================================================
function IsUnitAliveBJ takes unit whichUnit returns boolean
    return not IsUnitDeadBJ(whichUnit)
endfunction

Ну ты понял. =)
0
21
7 лет назад
0
Clamp, ага, всё понятно, то есть Alive и Dead проверки действительно лишние.
Пока получается так - может существовать фактически мёртвый юнит с количеством жизней, которое игра считает большим 0, и даже большим 1. Иначе не могу объяснить фатал.
Может, у меня там какой-то триггерный хил действует без проверки на мертвяков, хилит мертвяка и... gg.
Хотя вообще большинство функций у меня исключает мертвяков при проверке групп из обрабатываемых единиц, но... могло быть где-то пренебрежение для хила - типа он же мёртвый, какая разница, отхилится или нет, пока не реснется, не важно, а после реса все равно фулл хп будет. Ну вот разница и вылезла. Придётся эти пренебрежения искать.

И поставлю таки наверное вместо 1 конкретно в этой функции хотя бы 25, что ли, это будет не заметно в 99.5% случаев, а фаталы если и не устранит вообще, то сделает их еще меньше (их и ща мало, крокодилом было много норм игр сыграно, ему больше месяца уже и была вот дрочка с 6 ботами-крокодилами, но вот 2 раза таки вылезли).
2
30
7 лет назад
2
Если совсем по-тупому, то могу предложить создать глобальную группу "все юниты на карте", добавлять туда всех новых юнитов (кроме системных) и по событию смерти удалять из группы, тогда твоя проверка "живости" юнита будет заключаться в проверке нахождения в этой группе, и подобная бага не сможет появиться.

Но это очевидный костыль, хотя и красивый.
0
21
7 лет назад
0
Clamp, неплохо, подумаю
хотя если для конкретно этого спелла, проще что-то с одним крокодилом замутить, в других случаях пока проблем не замечалось, но все равно стоит иметь в виду такое глобальное решение (как минимум для героев)
ладно, пока, думаю, достаточно, как обновлю код, если еще понадобится - отпишу
4
16
7 лет назад
4
function IsDead takes unit u returns boolean
	return GetWidgetLife(u) < 0.405 or IsUnitType(u,UNIT_TYPE_DEAD)
endfunction
никогда не подводила
ну а портируемость в 99.9% не нужна, если ты специально не пишешь систему для людей. В моей карте системы используются только мной, и мемхак всецело мой же, варкрафт обновляться выше 26 не будет, поэтому плевать на то, что костыли местами.
0
30
7 лет назад
0
для людей
используются только мной

Себя я считаю человеком, и пишу тоже для себя ;-)

Собственно, ты умеешь и абстрагируешься от своих костылей, тут вопросов нет, но учить так делать неофитов - неверный подход. Они, не обладая твоей полнотой знаний и навыков, почти гарантированно начнут стрелять себе в колени, и с хорошими шансами никогда не смогут найти, чем именно.
0
21
7 лет назад
0
DracoL1ch, ага, збс, вроде то, что надо, занесу в кастом код себе для использования и с ней проверю
0
16
7 лет назад
0
ну давай будем честными, здесь ты назвал мемхак костылем и хаком, когда он таковым не является. использовать чтение и запись в большинстве случаев крайне просто. намного сложнее, если речь заходит о том, что надо патч накладывать на исполняемый код, но такое неофиту даже на пальцах объяснить сложно.
современный варкрафт задрочен на 90% и состоит из костылей на 50%, самых разных. нет ничего постыдного время от времени забывать кого-то из этого зоопарка. Некоторые нативки я для себя открывал спустя год после того, как уже занимался доткой профессионально.
0
32
7 лет назад
Отредактирован quq_CCCP
0
кароче юзай проверку
function IsUnitDead takes unit u returns boolean
    return IsUnitType( u, UNIT_TYPE_DEAD ) or GetUnitTypeId( u ) < 1
endfunction
Очень древняя функция которая, как считается 100% способна отличить мертвого от живого юнита, а так же не дать ничего сделать с удаленным или разложившимся юнитом.
Обычно юнит умирает с 0.405 хп, с 1 хп юнит еще жив. Поэтому нельзя проверять жив ли юнит функцией
function IsUnitDeadBJ takes unit whichUnit returns boolean
    return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
endfunction
0
16
7 лет назад
0
function IsUnitDead takes unit u returns boolean
    return IsUnitType( u, UNIT_TYPE_DEAD ) or GetUnitTypeId( u ) < 1
endfunction
единственный вариант, когда GetUnitTypeId() вернет 0, это если u==null. Но, внезапно, если юнит "протек", то он может еще висеть в памяти после уничтожения, и тип у него будет что ни на есть обычный, легитимный, хотя юнит уже технически мертв. Поэтому такая проверка просто бессмысленна.
0
30
7 лет назад
Отредактирован Clamp
0
когда он таковым не является
На мой взгляд, использование в качестве опорного элемента подсистемы (в данном случае карты) любого поведения, которое авторами исполняющей системы (в данном случае варкрафта) явно воспринимается как "неопределённое" или "нежелательное" есть костылирование; свою точку зрения не навязываю, но проясняю.

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

Обычно юнит умирает с 0.405 хп
Юнит никогда не будет иметь 0.405 хп, если ты их не выдашь ему кодом непосредственно перед проверкой.
0
16
7 лет назад
0
ну нееет, здесь как раз определенное - возвращается всегда значение армора и никакая погода на марсе на значение не влияет. Поведение полностью предпопределено, как и во всем мемхаке. Ошибки возникают, когда лезешь не туда или используется функция из игры, которая не готова к индивидуальному вызову (например, стек не чистит за собой и т.п.). Используя только чтение, можно быть уверенным в стабильности на 100%
0
30
7 лет назад
Отредактирован Clamp
0
определенное
Экспериментально? Если так считать, то да, определённо определено. Тобой, но, к сожалению, не стандартом. Ощути разницу подходов практическую и буквально на себе, если считаешь этого недостаточным: любая моя карта (да, не дота, но всё-таки) запускается на любой версии варкрафта, а ты после выхода БАГФИКСА вынужден был решать внутреннюю проблему, отвечая на вопрос "должен ли я соответствовать платформе, поскольку мой продукт от неё полностью зависим, или же это платформа должна неожиданно прогнуться под меня?", в итоге выбрав неверный ответ. Ничего лично против тебя не имею, ты близок мне по духу, много знаешь и умеешь, но объективно, это было глупое решение так увлекаться игрушкой, про которую ты точно знал, что её могут отобрать.
Извини, если обидел. С радостью обсудил бы этот момент подробнее в нормальном чате, дабы не разводить здесь оффтоп ЕЩЁ сильнее. Скинь в лс вк или телеграм, если интересно.
0
16
7 лет назад
Отредактирован DracoL1ch
0
да какие обиды, я про это не раз слышал. Время покажет.
Неопределенное поведение сродни чтению из области временной памяи - иногда там может быть армор, а иногда и мусор случайный. Если, читая из одного места, ты всегда получаешь единственно верный результат, то это детерминированное поведение. А сделана ли функция костылем или хаком, это вообще из другой оперы. Ты с определением попутал.
0
30
7 лет назад
0
DracoL1ch, я назвал не только "неопределённое".
Чтобы оставить комментарий, пожалуйста, войдите на сайт.