- 1
- 2
- 3
- 4
- 5
- 6
for (int i = 1; i <= s.Length; ++i) {
if (s[i] == '/') {
s = s.SubString(1, i) + s.SubString(i, MaxInt);
++i;
}
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+53
for (int i = 1; i <= s.Length; ++i) {
if (s[i] == '/') {
s = s.SubString(1, i) + s.SubString(i, MaxInt);
++i;
}
}
Кручу-верчу запутать хочу. Кто с первого раза догадается, в чём задача кода - получит пирожок с полочки.
P.S. Строки билдеровские, нумерация с 1. SubString принимает индекс начала и количество символов.
Vindicar 02.02.2015 09:26 # +17
TarasB 02.02.2015 09:43 # +17
bormand 02.02.2015 10:27 # +18
TarasB 02.02.2015 11:10 # +16
И да, я считаю это ограничение очень полезным.
Stallman 02.02.2015 11:28 # +14
?
kegdan 02.02.2015 11:34 # +19
bormand 02.02.2015 11:51 # +20
bormand 02.02.2015 11:55 # +17
kegdan 02.02.2015 12:06 # +20
max-wiz 02.02.2015 16:20 # +16
s := AnsiReplaceStr(s, '/', '//');
или регистронезависимо:
s := AnsiReplaceText(s, '/', '//');
Зачем изобретать велосипед?
bormand 02.02.2015 18:04 # +17
Чтобы был, ради стёба же. А настоящее решение с AnsiReplaceStr() я и так выше упомянул. Оно и для билдера и для делфи подходит, либа то одна.
> регистронезависимо
Заглавный слеш это что-то новое...
kegdan 02.02.2015 18:07 # +20
TarasB 02.02.2015 14:14 # +18
myaut 02.02.2015 14:52 # +16
TarasB 02.02.2015 16:20 # +17
Lokich 02.02.2015 14:44 # +16
bormand 02.02.2015 14:58 # +16
А вообще, емнип, нету.
Lokich 02.02.2015 15:04 # +15
Abbath 02.02.2015 22:19 # +15
bormand 02.02.2015 23:03 # +15
Abbath 03.02.2015 00:00 # +15
roman-kashitsyn 03.02.2015 00:50 # +17
kegdan 03.02.2015 01:06 # +15
спанч боб чтоли?
Abbath 03.02.2015 01:17 # +15
guest 03.02.2015 01:36 # +15
На входе характер c
На выходе 'c' != '/' ? c : "//"
Abbath 03.02.2015 01:45 # +15
2)Нахуй типизацию!
guest 03.02.2015 01:56 # +15
конечно же
guest 03.02.2015 01:58 # +17
э?
Abbath 03.02.2015 02:07 # +13
"//" - const char *
guest 03.02.2015 02:23 # +13
guest 03.02.2015 20:34 # +14
Самое ужасное то, что ты даже не понял, какую ужасную хуйню сморозил.
Stallman 02.02.2015 09:30 # +16
kegdan 02.02.2015 11:14 # +13
3.14159265 02.02.2015 13:44 # −8
Даже если он работает, то подобен человеку на одноколёсном велосипеде, который может ебнуться от малейшего изменения.
kipar 02.02.2015 13:56 # +11
bormand 02.02.2015 14:03 # +21
Т.е. то, что 8 из 10 опрошенных сказало "на первый взгляд, этот фрагмент удаляет слеши" не является проблемой? А ведь весь этот код вполне заменяется на один няшный replace...
kipar 02.02.2015 16:52 # +13
bormand 02.02.2015 18:07 # +12
Так и есть. У него чёрный пояс по SubString()'ам и Pos()'ам. И он любые операции над строками в этом базисе выражал... Вот еще выдержка из того кода (набросал по памяти, не ругайте):
TarasB 02.02.2015 21:17 # +9
3.14159265 02.02.2015 18:18 # −7
Подразумевает то что автор изобретает велик, но какой-то не очень удобный и медленный. А еще "8 из 10" не понимают как на нём ездить.
Изменение счётчика в цикле порождает хрупкий и откровенно херово сопровождаемый код.
guest 02.02.2015 23:46 # +12
guest 20.02.2015 19:13 # −1
kegdan 21.02.2015 08:03 # 0
guest 20.02.2015 19:14 # 0
inho 12.10.2017 13:06 # 0
> C++
Что за ебанутость?
bormand 12.10.2017 13:20 # +1
SemaReal 13.10.2017 03:16 # +5
bormand 14.10.2017 09:09 # +1
SemaReal 15.10.2017 08:21 # 0
я думал паскалевые, но двухбайтные
bormand 15.10.2017 09:23 # 0
SemaReal 15.10.2017 09:34 # 0
коу? он был мутабельный? оамама
bormand 15.10.2017 09:47 # +1
SemaReal 15.10.2017 09:51 # 0
мутабельные строки это охуенно
их удобно использовать в качестве ключа в ассоциативном массиве
Кстати! Знаете прикол про жабоебов и substring в седьмой+ жабе?
bormand 15.10.2017 10:08 # 0
COW строки прекрасно работают ключами в ассоциативных массивах. Лишь бы контейнер их по неконстатной ссылке не отдавал, когда перечисляет свои ключи.
> substring в седьмой+ жабе
Ну да, теперь он всегда копирует байтики. Кстати, а они не оставили какой-нибудь конструктор, чтобы создавать именно view на старую строку?
SemaReal 15.10.2017 16:33 # 0
bormand 15.10.2017 10:21 # 0
Автоматом.
SemaReal 15.10.2017 16:34 # 0
а вот в поцкале управление кучей было ручное, как в сишечке: getmem/freemem
я уверен был что и в дельфях было так же
inkanus-gray 15.10.2017 16:39 # 0
SemaReal 15.10.2017 16:43 # 0
Просто ващет говоря реализация автоматического рефкаунта это не оч простая задача, очень круто что борланд решил ее
bormand 16.10.2017 07:40 # 0
Там, на самом деле, майкрософт её решил, когда COM проектировали. А в делфи просто добавили поддержку COM-интерфейсов. А обычные объекты один хрен руками контролировали...
SemaReal 16.10.2017 22:25 # 0
Надо же IUnknown::AddRef делать
нет?
bormand 16.10.2017 22:33 # 0
От языка зависит... Где прикрутили нативную поддержку COM, как в делфи или VB - там конпелятор в нужных местах сам эти вызовы втыкает.
В крестах, в принципе, тоже можно руками ничего не делать (смартпоинтеры).
Вручную AddRef дёргают разве что в няшной.
SemaReal 16.10.2017 23:41 # 0
В общем я понял (благодаря тебе) что рефакаунтинг вовсе не так сложно, как я думал. Правда, в нем некоторое количество лишних действий (например inc на каждый return, если не испозовать policy как у яблока), но мне стало совсем не понятно зачем выдумали GC.
Неужели только ради циклических ссылок (которые рефкаунту обычно не разрулить)?
roman-kashitsyn 16.10.2017 23:47 # +1
GC собирает объекты в ширину, RC — в глубину. Т.е. если сделать глубокое дерево, наивное RC может порвать стек когда корень выйдет из скопа. Односвязный список — это как раз такое дерево, к примеру.
Ну и GC компактификацию кучи может делать.
SemaReal 16.10.2017 23:52 # 0
>>компактификацию
Это как дефрагментацию, да?
Интересно было бы совместить оба подхода, чтобы программист мог сам выбирать поведение для программы. У яблов можно было когда-то опционально включать GC, но давно уже нет
bormand 17.10.2017 07:06 # 0
Минус - очень дорогая и недетерминированна я финализация объектов, если она вдруг понадобится.
subaru 17.10.2017 00:53 # +1
Это не так, погугли RVO. Оптимизирующий компилятор может выкидывать лишние копирования указателей и за счет этого устранять лишние пары инкримент-декримент. Кроме того, в плюсах и в расте в язык встроена мувсемантика, за счет которой временные смартпойнтеры не копируются, а перемещаются, не меняя счетчик ссылок. Так что там даже без специальных оптимизаций со стороны компилятора не будет лишних операций с рефкаунтером при возврате указателя из функции.
SemaReal 17.10.2017 01:01 # 0
Как у вас всё хорошо. стану крестобляпрограммистом, пожалуй
bormand 17.10.2017 06:59 # +1
В крестах за счёт мув семантики и RVO лишние вызовы инкремента уйдут.
subaru 17.10.2017 12:50 # +1
SemaReal 17.10.2017 20:41 # +1
bormand 15.10.2017 16:51 # 0
SemaReal 15.10.2017 16:57 # 0
Функция Foo создала на куче объект и вернула нанего ссылку.
У объекта каунт=1, иначе бы он сразу же умер.
Взявший его код увеличил каунт на 1. Получилось 2.
А после ухода указателя из области видимости опять стало 1.
Кто уменьшит этот 1 до ноля?
bormand 15.10.2017 17:02 # 0
SemaReal 15.10.2017 17:04 # 0
function Foo() {
return new Bar();
}
в каком месте компелятор тут что воткнет?
subaru 15.10.2017 17:21 # 0
SemaReal 15.10.2017 17:23 # 0
bar = Foo();
//и тут использую bar
subaru 15.10.2017 17:28 # +1
SemaReal 15.10.2017 17:56 # 0
Он знает что есть функция, возможно в библиотеке, которая возвращает какой-то указатель.
Вот я получил этот указатель. Его рефкаунт должен быть больше ноля (иначе объекта бы уже не было), значит, увеличить должна была функция в момент создания.
Хорошо. Тогда я должен всегда уменьшать его на один как только я получил его из функции.
но что если функция его не создает, а возвращает синглтон или там static storage duration?
Как клиенту узнать -- создала-ли его функция специально для меня (чтобы я уменьшил каунтер) или нет?
bormand 15.10.2017 17:58 # 0
На них же держит ссылку некая глобалка, не тупи.
SemaReal 15.10.2017 17:59 # 0
Как этот кто-то узнает что его можно удалить?
А если это филд объекта?
bormand 15.10.2017 18:04 # 0
Ну вот выйдет у тебя глобалка из скопа (аля конец программы) или в неё ссылку на другой объект или null засунут - тогда и удалится.
> если это филд объекта
Сдохнет объект и позовётся декремент на всех его полях, которые содержат не null ссылки. Очевидно же.
З.Ы. Вот теперь настоящий Сёма детектед.
SemaReal 15.10.2017 18:07 # 0
Foo() возвращает этот объект
ты хочешь сказать что на каждый вызов Foo() будет декремент каунта?
bormand 15.10.2017 18:12 # 0
Да, будет. На каждый, блять, вызов. Хотя конпелятор имеет право убрать пару из подряд идущих инкремента и декремента (например в b = Foo() или return Foo()), чтобы время зря не тратить.
Всё, заебало, пойду лучше в кружки поиграю.
SemaReal 15.10.2017 18:25 # 0
тогда синглтону пиздец придет
его каунт станет равен нолю через пару вызовов
Я там внизу пример привел, ты бы лучше над ним подумал, прежде чем злиться.
То, о чем я говорю, называется Ownership Policy, и это совсем не так просто как вы тут с субару пытаетесь мне рассказать.
bormand 15.10.2017 18:28 # 0
Дык он же инкрементит его каждый раз, когда отдаёт кому-то. Поэтому баланс инкрементов и декрементов соблюдается.
SemaReal 15.10.2017 18:31 # 0
bormand 15.10.2017 18:37 # 0
Да, так. Именно так работают intrusive ptr и shared_ptr в крестах.
З.Ы. Почитал этот ваш Ownership Policy - те же яйца, только сбоку. If an existing object is returned, its retain count is incremented so it is your responsibility to relinquish ownership.
subaru 15.10.2017 18:26 # 0
Верно.
> что если функция его не создает, а возвращает синглтон или там static storage duration?
Тут есть две опции. Одна - у владеющих и невладеющих указателей должен быть разный тип. Вторая - у указателя должен быть флажок, по которому в рантайме можно узнать, владеет ли он объектом.
SemaReal 15.10.2017 18:34 # 0
третье это по имени функции понимать policy: создающие объект и возвращающие существующий могут иметь разные префиксы
Как видишь автоматический рефкаунтинг не так прост, все решения не выглядят слишком элегантнор
bormand 15.10.2017 18:56 # 0
Кстати, а как Ownership Policy в ObjectiveC дружит с многопоточностью?
По Get Rule мне вернули существующий объект и, если он мне нужен, я должен позвать CFRetain. А если за это время объект уже сдох?
З.Ы. А, ну ясно: Moreover, it is usually not possible to achieve absolute thread safety at this level. You cannot rule out, for example, indeterminate behavior resulting from retaining an object obtained from a collection. The collection itself might be freed before the call to retain the contained object is made.
Дооптимизировались. Описанная мной в этом треде политика, когда во всех случаях работает Create Rule, выглядит проще и безопасней (хотя и чуть медленнее из-за инкремента/декремента).
bormand 15.10.2017 17:56 # 0
В принципе, subaru всё правильно объяснил.
Ну всё тривиально же:
1) new возвращает временную ссылку со счётчиком 1
2) a = b инкрементит счётчик у b и декрементит у a (если там был не null)
3) return инкрементит счётчик
4) выход ссылки из скопа декрементит счётчик
5) пару inc+dec можно выбросить, если хочется оптимизации
SemaReal 15.10.2017 18:01 # 0
почему
a = b
вдруг уменьшает рефканут у b?
А если Foo() вернет ссылку на синглтон то через пару вызовов он помрет/
bormand 15.10.2017 18:06 # 0
> ссылку на синглтон
Как он блять помрёт, если реализация синглтона держит в себе ссылку на этот объект? Чтобы её же вернуть второму клиенту, который придёт после тебя?
SemaReal 15.10.2017 18:16 # 0
class Foo{
function bar(){return this}
function eggs(){return new Spam();}
}
///в другом месте////////
foo = new Foo();
foo->bar();
foo->eggs();
На последней строчке нам возвращается объект с рефкаунтом 1 и надо бы как-то его уменьшить, иначе он не помрет никоглда
на предпоследней строчке нам возвращается объект с рефкаунтом 1, но его уменьшать не надо потому что метод его рефакунт не увеличивал.
Учти что компилятор НЕ ЗНАЕТ что там внутри класса Foo происходит.
Вызовы для него одинаковы, а поведение должно быть разное.
Если он всегда будет уменьшать счетчик, то два вызова bar() разрушат объект
а если не будет -- то после вызова bar() будет утечка
bormand 15.10.2017 18:24 # 0
Ну схуя? Поведение будет одинаковое - и после foo->bar() и после foo->eggs() он позовёт декремент (rule 4).
return this увеличит счётчик на 1 (см. rule 3), поэтому bar() вернёт объект с рефкаунтом 2 и он выживет.
return внутри eggs() тоже увеличит счётчик (rule 3), но выход временной ссылки из скопа (которую вернуло new) уменьшит его (rule 4), поэтому из eggs() вернётся объект с рефкаунтом 1 и он сдохнет.
Включи мозги уже, блин.
SemaReal 15.10.2017 20:46 # 0
Что ты так разнервничался? Первый раз ламера в Интернете увидел?
bormand 15.10.2017 22:47 # +1
Сорри, у меня синдром утёнка случился - я не знал, что в ObjectiveC используется более сложная схема рефкаунтинга, чем обычно (вот это самое разделение на Create методы, которые инкрементят и Get методы, которые не инкрементят).