- 1
- 2
- 3
- 4
- 5
std::vector<int> vec = { 1, 2, 3, 4 };
for (auto i = vec.size() - 1; i >= 0; i--) {
cout << i << ": " << vec[i] << endl;
}
cout << endl;
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+4
std::vector<int> vec = { 1, 2, 3, 4 };
for (auto i = vec.size() - 1; i >= 0; i--) {
cout << i << ": " << vec[i] << endl;
}
cout << endl;
Выстрел в ногу, заботливо прикрытый фиговым листочком «auto».
Elvenfighter 30.09.2017 10:33 # +2
Dummy00001 30.09.2017 18:01 # 0
gost 30.09.2017 22:01 # +1
И только -Wextra заставляет нас прозреть:
Antervis 30.09.2017 18:58 # +1
хотя кто-то там на выступлении говорил аля "мы чет зря не сделали размеры контейнеров int'ами"
d_fomenok 30.09.2017 19:09 # −1
Давно уже пора выпилить unsigned, а лучше запретить по закону
Antervis 30.09.2017 19:57 # 0
inho 30.09.2017 22:10 # +1
gost 30.09.2017 22:32 # 0
Antervis 01.10.2017 12:11 # 0
j123123 30.09.2017 20:26 # 0
d_fomenok 01.10.2017 08:58 # 0
qazwsx 11.10.2017 23:29 # 0
FrauSchweinhund 11.10.2017 23:52 # 0
roman-kashitsyn 12.10.2017 09:18 # +3
Если вдруг захочется сёрвить кусок поискового индекса, замапленного в память, с 32-битной машины. Сейчас amd64 повсеместен, и проблема уже не так актуальна, как лет 15 назад.
bormand 12.10.2017 09:26 # +3
Ну раз всё равно кусок - значит можно на той же машине поднять второй инстанс (а может и ещё несколько, если PAE работает и физической памяти хватает).
FrauSchweinhund 12.10.2017 13:52 # +3
SemaReal 12.10.2017 03:20 # +3
inkanus-gray 12.10.2017 03:36 # 0
qazwsx 12.10.2017 11:21 # 0
ДОС работал и на тех и на других.
inkanus-gray 12.10.2017 17:24 # +2
Размер указателя был 32 бита и хранил он не линейный адрес, а запись из двух полей: сегмент + смещение. В упомянутых реализациях Си/C++ был даже нестандартный оператор :> для сборки указателя из сегмента и смещения.
В реальном режиме процессора (ДОС) эти 32 бита преобразовывались в 20-битный линейный адрес (сегмент тупо умножался на 16 и к нему прибавлялось смещение), а в защищённом (Windows) сегмент заменялся на базовый адрес из таблицы дескрипторов и к нему прибавлялось смещение, а результат мог занимать 32 бита. Но этот линейный адрес прятался где-то в глубинах процессора, а со стороны программ не был виден.
Так что к указателям было проще относиться как к «чёрному ящику».
Сегментная адресация применялась и на 32-битных машинах (PAE позволяла адресовать 64 гигабайта вместо 4), но уже считалась экзотикой.
*****
Так что в итоге делать с указателями в общем случае? У меня два варианта:
1. Считать указатель «чёрным ящиком», неким объектом фиксированного размера (не обязательно совпадающим с размером линейного указателя). Так было сделано в компиляторах для DOS и Windows 3.x.
2. Сделать указатели линейными, а в компилятор для машин с сегментной адресацией встроить транслятор, который будет преобразовывать указатели туда-сюда. Это негативно скажется на производительности.
qazwsx 13.10.2017 00:19 # 0
К чему я это все. К тому, что к стандартному С++ это не имеет прямого отношения. Разработчики языка руководствуются двумя основными правилами: zero overhead abstractions and direct mapping to hardware. В следствии чего стандарт игнорирует сегментную адресацию, PAE и все такое. Есть абстрактное понятие storage, есть линейная адресация внутри него и есть типы, которые мапяться на регистры доступной разрядности. Я специально уточнил, что речь о стандарте языка(т.к. в примере кода стандартный контейней), которому всякие расширения или достандартные компиляторы не соответствуют просто по определению.
inkanus-gray 13.10.2017 00:37 # 0
qazwsx 13.10.2017 01:15 # 0
subaru 13.10.2017 01:17 # 0
qazwsx 13.10.2017 01:36 # 0
SemaReal 13.10.2017 03:50 # 0
Это "unreal mode". Говнохак, очень популярный в игрушках.
>>dos4gw
ЕМНИП dos4gw использовал API "expanded memory" а не unreal mode.
>>В защищенном режиме в сегментные регистры помещаются селекторы дескрипторов
В 32 да, но мне кажется что в long mode уже нет. Там только pages.
>>абстрактное понятие storage, есть линейная адресация внутри него
Согласен. Но если мы пишем для tiny mode (все сегментные регистры указывают на начало, а размер памяти ограничен 64К) то у нас линейное пространство:)
inkanus-gray 13.10.2017 04:36 # +6
inho 13.10.2017 10:01 # +4
А СёмаРеал - это бароп
а кто бароп - не знаю
bormand 13.10.2017 16:37 # +3
subaru 13.10.2017 17:02 # +2
bormand 13.10.2017 17:05 # +3
subaru 13.10.2017 17:07 # +4
defecate-plusplus 13.10.2017 21:25 # +4
голубой шильдик и оппозитный двигатель это уже диагноз так-то
inkanus-gray 13.10.2017 21:45 # +4
defecate-plusplus 13.10.2017 23:26 # +4
Но прочитав свой коммент второй раз, теперь тоже вижу явный гомосексуальный контекст.
inkanus-gray 13.10.2017 23:44 # +3
Кстати, а V-образный двигатель с развалом 180 градусов лучше оппозитного?
inho 16.10.2017 09:50 # 0
это не я, инфа 100%
А кресты можно за год выучить
gost 16.10.2017 11:32 # 0
Это не я.
За 20 дней же.
qazwsx 13.10.2017 19:26 # 0
Селекторы это часть механизма защиты в защищенном режиме, они не должны никуда деться.
Я привел это в качестве примера вещей никак не связанных с С++. Ты понял, что я изначально писал конкретно про С++, про плюсовую memory model и типы завязанные на нее? Если да, то у тебя по прежнему есть возражения?
Вообще у меня есть такое наблюдение. Если задать вопрос джуну, то в ответ он выльет вот такой вот таз деталей реализации, про оффсеты и прерывания, баги MSVC, что у него скомпилилось, а что нет, без какой либо попытки ответить в терминах стандарта. Изначально вопрос стоял про стандартный вектор и рассматривать его в отрыве от стандарта, приплетая досовые компиляторы из 90х - дичайшее аматорство.
subaru 13.10.2017 19:41 # 0
Пока что ты не привел ни одного пруфа своему пездежу кроме сомнительной ссылки на анскильный бложик васянов из тулы.
qazwsx 13.10.2017 22:43 # 0
Ну чё ты такой сердитый человек-то, ну будьте людьми вы, ребята, я всегда вам говорю. Чего вы сразу начинаете?
subaru 13.10.2017 23:39 # +1
> Важно, что модель памяти С++ ограничивает тебя только адресами, которые помещаются в size_t.
> Просто стандарт С++ не поддерживает никаких "других" платформ.
subaru 13.10.2017 23:44 # +3
qazwsx 14.10.2017 00:22 # 0
Выходит я был не прав, по поводу других платформ и непрерывной памяти. Признаю свою ошибку. Ты хамло, но спасибо, что обратил мое внимание на эти детали. Удивительно, как оно все это время ускользало... Пойду напьюсь теперь.
SemaReal 13.10.2017 22:22 # 0
У меня для тебя дурные новости, чувак.
В середине восьмидесятых появилась страничная адресация, и теперь механизмы защиты есть и на уровне страницы тоже.
В long mode (aka x64) от сегментов практически избавились кроме парочки.
>>Если да, то у тебя по прежнему есть возражения?
Если ты почитаешь внимательнее, то увидишь что я с тобой не спорил.
Я совершенно согласен с тем, что С оперирует понятием "storage" и как должны вести себя указатели (в плане арифметики и разыменовывания) там тоже описано.
А как устроена памяти конкретной машины (есть там сегменты или еще что) -- это эквопенсиуально
qazwsx 13.10.2017 22:37 # 0
Давай ладом. Селекторы отдельно, таблицы страниц отдельно. В сегментные регистры помещаются селекторы, указатель на таблицу в отдельный регистр. Прочитай то, что я написал еще раз.
> Если ты почитаешь внимательнее, то увидишь что я с тобой не спорил.
Конкретно в этом сообщении нет, но чуть выше разве не ты писал?
> Вообще никакой связи может не быть с размером адресного пространства и размером конкретного типа.
Так ты согласился с моим утверждением или оно все еще кажется недостаточно точным?
В том случае, который я описал, есть связь или нет никакой?
SemaReal 13.10.2017 22:47 # +1
И? Как это противоречит тому, что я написал выше?
В 286 были только сегменты для защиты
В 386 и сегменты и страницы (только сегменты современные ОСы перестали для этой цели юзать)
в x64 и вовсе случился:
"In 64-bit mode, segmentation is generally (but not completely) disabled, creating a flat 64-bit linear-address space. The processor treats the segment base of CS, DS, ES, SS as zero, creating a linear address that is equal to the effective address. The FS and GS segments are exceptions. These segment registers (which hold the segment base) can be used as an additional base registers in linear address calculations. They facilitate addressing local data and certain operating system data structures."
Где тут защита-то?
>>В том случае, который я описал, есть связь или нет никакой?
Тот случай, это который?
Это
"Знаковый тип позволит адресовать только половину доступных адресов. Это и есть та причина, по которой размер стандартных контейнеров без знаковый.
"?
Ты пытаешься объяснить почему size_t в стандарте беззнаковый?
qazwsx 13.10.2017 23:21 # 0
Участвуют сегментные регистры.
Да, но я не пытаюсь объяснить. Я уже объяснил, не только почему он беззнаковый, но и почему в векторе используется именно он. Казалось бы очевидная вещь, но не все понимают. Делюсь информацией, только и всего.
SemaReal 14.10.2017 00:19 # 0
Вот да. Сегментация могла-бы в 32 mode юзаться для защиты памяти, но не юзается. А в 64 выпелена вовсе (точнее там как бы один большой сегмент размером со всю память).
Но размер сегмента это всего лишь одно из полей дескриптора. С тем что другие поля (DPL там всякий, да собственно и поле с указанием разрядности) юзаются я не спорю.
>не только почему он беззнаковый,
Что мешало сделать его знаковым, а работу с отрицательными значением объявить UB?
qazwsx 14.10.2017 00:32 # 0
SemaReal 14.10.2017 00:39 # 0
Я вот зацепился именно за это утверждение.
Допустим у меня sizeof(int) == 32, при этом максимально доступное адресное пространство 2^16.
Ну вот такая глупая система. Но что помешает мне ее создать?
qazwsx 14.10.2017 00:56 # 0
SemaReal 14.10.2017 01:15 # +1
действительно. Ну тогда
-32
+4
SemaReal 13.10.2017 03:44 # +3
Давайте сразу оговоримся что адрес имел формат СЕГМЕНТ:СМЕЩЕНИЕ (оба по 16 бит) а как они мапились в реальные запросы (что выставлял на шину адреса проц) это отдельная песня.
Вот указатель мог быть ближним, и тогда он содержал только смещение.
При разыменовывании сегментный регистр никто не трогал, и потому если программист поменял значение сегментного регистра и забыл об этом, то указатель становился невалидным.
При адресной арифметике он просто перехлестывался через 64К делая невозможным хранение объектов большего размера.
Был far pointer, он имел еще и СЕГМЕНТ и перед разыменовыванием загружал его в регистр. Но адресная арифметика работала так же.
А был еще huge который умел менять сегментный регистр при адресной арифметике. Он был жутко тормозной, но позволял делать вид что он почти линейный.
При установке адреса на шину он "срезался" до 20 бит и потому можно было попасть в один и тот же кусок памяти разными способами. Говнокодеры полюбили этот прием, и когда адресную шину увеличили до 24 то оставили эмулятор старого поведения (см. Gate A20).
Товарищ внизу правильно говорит что с точки зрения стандарта это хуйня, но в стандарте не было понятия "far pointer".
inkanus-gray 12.10.2017 03:38 # +2
qazwsx 12.10.2017 11:10 # 0
subaru 12.10.2017 14:24 # +3
> std::size_t can store the maximum size of a theoretically possible object of any type (including array).
> On many platforms (an exception is systems with segmented addressing) std::size_t can safely store the value of any non-member pointer, in which case it is synonymous with std::uintptr_t.
qazwsx 12.10.2017 23:12 # 0
subaru 13.10.2017 00:06 # 0
qazwsx 13.10.2017 00:53 # −1
Такое может предложить только петух или питонист.
Тут нет совпадения. Просто стандарт С++ не поддерживает никаких "других" платформ. Это не значит, что их нет. Просто понятие адреса определено, без учета их особенностей.
subaru 13.10.2017 01:13 # 0
inho 13.10.2017 10:05 # 0
P.S. Я тоже ламер.
inkanus-gray 13.10.2017 10:16 # +2
Antervis 13.10.2017 11:00 # +5
а коли не пашет - сам иди на хуй
SemaReal 13.10.2017 22:24 # +4
Потом оказывается что я захардкодил "c:\documents and settings\semareal" в семи местах
FrauSchweinhund 14.10.2017 00:54 # +1
Вот ты пошутил, а мне с этим работать на работе приходится.
SemaReal 14.10.2017 00:55 # 0
FrauSchweinhund 14.10.2017 00:56 # +1
SemaReal 14.10.2017 01:09 # 0
FrauSchweinhund 14.10.2017 01:45 # +1
(не пхп)
SemaReal 14.10.2017 02:37 # +4
На Dart пишете?
bormand 14.10.2017 09:01 # +5
Да уже сдеанонили, походу. Они же тоже знают, что язык редкий и пути захардкоженные в проекте есть.
SemaReal 13.10.2017 03:53 # +2
я могу изобрести копелятор в котором sizeof(short) == sizeof(long) == 8
а sizeof(size_t) == 64
Это тупо,нобудет же работать
inho 12.10.2017 23:50 # +2
subaru 12.10.2017 23:52 # 0