- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
#include <iostream>
using namespace std;
struct Rooster {
int id = 0;
};
void asshole(const Rooster* roosters) {
Rooster* r = (Rooster*)roosters;
for (int i = 0; i < 3; i++) {
r[i].id = i + 1;
}
}
int main() {
Rooster roosters[3];
asshole(roosters);
for (int i = 0; i < 3; i++) {
printf("%d\n", roosters[i].id);
}
return 0;
}
И вообще, представь, что "asshole" писал не я. Я просто передал в функцию const.
>скобочки короче
ну ёбвашумамку, скобочки имеют мутную семантику (расщирение типа? снятие каста? трактовка тех же данных по другому?), а касты такой проблемы не имеют. Не нужно в крестах скобочек.
Я тебе там ниже покушать принес
это из разряда #define true false и т.п.
Удаление оттудава конст приводит к ошЫбке
[q]
prog.cpp:18:13: error: invalid conversion from ‘const Rooster*’ to ‘Rooster*’ [-fpermissive]
[/q]
Кстати, это ошибка же только в С++? в си это был бы варнинг?
ну в любом случае, это не прошло бы незамеченным
https://ideone.com/v7XWm0
Всего лишь ворнинг:
Вот Dummy0001 (правильно написа́л его юзернейм?) любит повсюду писа́ть слово «struct». Вот ему Rooster_tag пригодится.
Перевёл на язык «Dummy0001»:
Ничего не забыл или надо ещё побольше слов «struct» напихать?
https://en.cppreference.com/w/cpp/language/consteval
Главное — не перепутать, где использовать «constexpr», а где «consteval»:
Правда, простой и понятный язык?
constexpr может в любом.
Отсюда нельзя consteval использовать от переменных, переданных в constexpr.
Так же?
У них ещё и constinit есть:
https://en.cppreference.com/w/cpp/language/constinit
Это когда мы хотим убедиться, что начальное значение переменной является константой, чтобы оно попало в бинарник, но дальше мы значение переменной хотим изменять.
Таким образом, constexpr ещё не гарантирует, что оно всегда будет константой. Это только хинт для компилятора, что тут можно оптимизировать.
consteval же гарантирует, что выражение будет вычисляться на этапе компиляции, поэтому зашкваривает его, и в неконстантном контексте его уже вызвать нельзя.
Если мы зашкварили функцию атрибутом consteval, то для того, чтобы такой же код использовать с переменным аргументом, его придётся продублировать (под другим именем).
constinit же придумали для привередливых, которые хотят убедиться, что начальное значение будет посчитано на этапе компиляции и попадёт в секцию данных.
Ничего не перепутал?
Сделали бы уже простую двухпроходную схему.
1. Везде, где нужна константа времени компиляции, выражение заключается в вызов const
2. При компиляции программа запускается, значения внутри const берутся из памяти и сохраняются для вставки в скомпилированную версию
3. Для сложных кобенаций указателей сделать operator char* + constructor (char*) или отдельные операторы сериализации-десериализации (вообще, стандартные они бы пригодились и без этого). Компилятор может соптимизировать десериализатор, если что.
Всё. Не нужно наворачивать говна, сильно усложнять компилятор и стандарт.
https://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions
Кстати, что оно там означает?
> Кстати, что оно там означает?
Сам себе ответил же:
> this has type const Array*
Я же недавно рассказывал, что у жабоебов и шапеев этого нету, и потому ни вынуждены плодить интерфейсы (так им и надо, анскилябрам заедушным)
А ещё методы можно перегружать по константности:
Хороший пример использования такого подхода — реализация begin()/end() в итераторах. Это очень удобно тем, что не нужно беспокоиться о константности ссылки, «for (auto it = vec.begin();...)» сработает и для «T &», и для «const T &», причём во втором случае it будет константным итератором.
Именно поэтому…
const Petuh h;
h.koko();
и
Petuh h;
h.koko();
это РАЗНЫЕ методы?!
Какой С++!!
буду курьером
А у тебя был?
Если пары жидкости растворимы, они осаждаются на слизистых и в дальнейшем проникают в слюну, которая может проглатываться, кроме того, всасывание происходит на всей поверхности пищеварительной трубки, начиная от полости рта и кончая в толстой кишкой.
Именно поэтому работать с химикатами на голодный желудок гораздо опаснее, чем на сытый.
в плюсах копилится, в сишке -- нет
почему?
Чтобы объявить обычный массив (не динамический!), в качестве его размера нужно задать чистую константу.
но VLA бывает только автоматический, небось, смысли на стеке
Тут roosters[N] будут созданы в стеке тупо декрементом указателя на вершину. На этапе компиляции значение N знать не нужно.
А вот в глобальном контексте в «Plain C» не компилируется.
Это сокращение "Владимир"?
• Внутреннее обозначение аэропорта Владикавказа.
• Великая ложа Англии.
• Very large array = сверхбольшая антенная решётка (радиотелескоп).
надо бы туда слетать, выпилить одного рака
В ++ тоже
int petya = 5;
const int petr = petya;
Падает во время исполнения, потому что линкер поместил N в секцию .rdata. На платформе же без секции .rdata значение N будет подменено.
MS: надо всегда делать typedef, чтобы никогда не писить struct. В Win32API ВСЁ через typedef.
Unix: надо всегда делать struct.
А ты за кого?
Rooster* r = (Rooster*) roosters;
/fxd
Но спасибо хоть на такое ворнинг
А вот без каста в крестах будет ошибка.
То, про что говоришь ты, там тоже можно
Это называется "мягкая ссылка" (а через бекслеш -- жесткая)
ps
our -- это глобальная (уровня пакета) переменная.
Она видна через тн glob: *myvar{'SCALAR'}.
Для my бы не сработало
В большинстве языков (ruby,JS, java,ObjC, Kotlin, C# (исключая value type), python, lua) "примитивные" (скалярные?) типы передаются по значению.
А сложные типы --по ссылке. Причем, это происходит автоматически.
Считаете-ли вы это полжительным фактором, или лучше как в C/C++?
В Perl нескалярный тип вообще нельзя передать по значению (он развалится на массив, из которого состоит, если не использовать сигнатуры)?
int x = 42;
x.changeTo(3); // так низя
Но ты прав: дело в их иммутабельности.
У примитивов есть еще одно забавное свойство: если они равны, то они эквивалентны.
С этим связан один прикол, который любят спрашивать жабоёбы на собесах.
Для примитивов и для объектов используются разные алгоритмы сортировки, почему?
Потому что для примтивов мы можем использовать нестабльный алгоритм: 42 и 42 можно поменять местами, и ничего за это не будет.
А вот petuh1 и petuh2 нельзя, даже если petuh1.equals(petuh2)
Doctor described his condition as stable
Pack — это собачья стая.
School — это косяк рыб.
Congress — это стая бабуинов.
Pod и flock — это птичья стая.
Float — стая крокодилов.
Safe — утиная стая.
Array — стая ежей.
Host — колония кузнечиков.
Committee — стая мангустов.
Parliament — совиная стая.
Cluster — колония пауков.
Да и хуй с ними.
Швейк знал двух Фердинандов:
Один служит у фармацевта Пруши. Как-то раз по ошибке он выпил у него бутылку жидкости для ращения волос; а еще есть Фердинанд Кокошка, тот, что собирает собачье дерьмо. Обоих ни чуточки не жалко.
У рыб это будет косяк(с)
Нестабльная -- не гарантирует
Капитан
Откуда мне знать что требуется стабильная сортировка?
Для примитивов используется qsort: он может быть быстрее, но нестабилен. Для объектов merge sort.
Впрочем, для последних джав они могли это поменять
Бывают правда чуваки, которые кроме пузырька ничего не помнят наизусть
даже число 4?
Можешь посмотреть реализацию:
https://github.com/python/cpython/blob/master/Objects/longobject.c
Видимо это сделано для единнообразности: работать с большими и маленькими числами удобнее одинаково, даже если мы и теряем немного времени на ненужной (с точки зрения байтойоба) операции, ведь мощность указательного типа на современных архитектурах может превышать мощность типа, необходимого для хранения небольших чисел.
Кажется, в Ruby раньше для больших и малых чисел использовались разные типы (с автоматическим превращением, разумеется), но возможно что это уже не так.
Приятнее всего портить что-то в Ruby, там для этого есть все возможности
В Perl так же присутствуют мощные инструменты для портинья
А вот с перлом интересно, для чего изначально было придумано overload::constant?
https://metacpan.org/pod/overload#Copy-Constructor
Юкихиро Мацумото сказал, что они не нужны.
Питонисты просто пишут
foo += 1
и текут
Про объекты в Obj C ты правильно пишешь, но вот остальные типы данных там один в один сишные и ведут себя ЕМНИП как сишные. Думаю, что структуры сишные в Obj C методы тоже можно передавать всеми известными способами, но проверять лень
В этом смысле Свифт другой: там есть чёткое разделение на value и reference прямо на уровне языка. Как по мне, то в прикладухе такая ясная семантика важнее, чем некая условная гибкость
Вероятно, речь тут о том, что в С и С++ программист сам решает, как ему передавать объект: может скопировать, а может передать ссылку или указатель, причем передавать указатель можно даже для объекта на стеке (и разумеется всегда для объекта на куче, так как доступа к нему кроме как через указатель нет).
Речь конечно о ситуации, когда программист имеет контроль и над вызываемой функцией тоже.
ObjCные же объекты всегда располагаются на куче (кроме блоков, кажется, но и те копируются при передаче наружу) и у программиста нету выбора где из создать (и, соответственно, как их передать).
Разделение на value и reference мне нравится.
А можно передать по ссылке value object?
Я спрашиваю, потому что например в C# можно (хотя по умолчанию он конечно скопируется) а например в Java -- нельзя
- формально да. Фактически происходит двойное копирование.
https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID545
Но, честно говоря, не помню даже, когда бы писал функции с inout
Придется делать спец. интерфейс, и указывать его в сигнатуре функции.
в С++ это решается const, именно потому я за
Вообще, как завещал [забыл как его фамилия], геттеры и сеттеры нинужны.
В python и ruby так конечно не делают (там джентельменское соглашение), а в java очень даже.
В C# хотя-бы есть сахар для этого.
В С++ я бы просто пометил аксессор как конст, и потек
Именно поэтому я за "-pedantic-errors".
нууу
эээ
ммм
Это же си, чувак. Тут можно сделать всё, что угодно.
Ты можешь взять число 1234 и скастить его в указатель на массив интов, и что-то там поправить по этому адресу с известными последствиями.
Хочешь, чтоб такое вообще не компилировалось?
Так точно. Список того, что делают скобочки, очень длинный, и в уме это просчитать трудно, обязательно какой-нибудь из вариантов упустишь из виду. В крестах лучше более явные касты.
*почти
Имею привычку не использовать «unsigned» при итерации.
Также имею привычку при сравнении «unsigned» и «int» приводить к «int».
И я за «size_t».
Выкуси.
угадай, что тут будет
Я как-то углублялся в асм под реальный режим, и это была одна из моих попыток в нем прокачаться.
Это было года 3-4 назад, я только учил асм, сейчас тот код мне кажется глупым. Может быть если использовать байт-код и вынести заголовки отдельно и уместится, но я стал гораздо более ленивее.
Кстати, я тогда не ладил с родителями и мне не разрешали садится за комп, я написал эту системку на смартфоне и собирал и отлаживал её также на смарте в досбоксе )))
Кстати об ОС и маленьких программах, когда-то на форуме фасма проводилась специальная олимпиада на 512-батную ОС, в посылках были всякие аналоноги досовских дебагеров и тетрисы, а первое место заняла многозадачная Nano OS да ещё и с тремя демо-приложениями для теста.
Тут есть архив с посылками:
http://board.flatassembler.net/topic.php?t=2164&postdays=0&postorder=as c&start=140
Чувствую себя анскилляброй(
Почему, например, у меня одна папка node_modules весит 8,9 мегабайт тогда?
Может, как-то неправильно мы программируем компьютеры?
https://www.npmjs.com/package/is_number
https://www.npmjs.com/package/@nathanfaucett/is_number
https://www.npmjs.com/package/@jwaterfaucett/is_number
Три пакета, определяющие, является ли аргумент числом.
https://www.npmjs.com/package/is_string
https://www.npmjs.com/package/@indlekofer/is_string
https://www.npmjs.com/package/@jwaterfaucett/is_string
Три пакета, определяющие, является ли аргумент строкой.
https://www.npmjs.com/package/is_boolean
https://www.npmjs.com/package/is_finite
https://www.npmjs.com/package/is_null
https://www.npmjs.com/package/is_object
https://www.npmjs.com/package/is_empty
https://www.npmjs.com/package/is_undefined
https://www.npmjs.com/package/is_nan
Тоже очень нужные пакеты.
JS был создан за пару недель без какого-либо глубокого анализа, и потому люди используют внешние пакеты для провери на is_null.
В других языках такой проблемы нет
К нему прилагаются юнит-тесты, метаданные пакета, Gruntfile.js, .travis.yml и ещё какая-то поебень.
Вполне может вознинуть такая задача в реальном приложении.
На этот случай я советую воспользоваться моим модулем. Модудь распостраняется по GPL, то-есть совершенно бесплатен.
В настоящее время к выпуску готовится модуль isNotSergievPosad, обладающий схожим функционалом.
Кроме шуток: они там все ненормальные чтоли?
А тест есть?
NPM работает на пользу Node.js, где есть своя удобная стандартная библиотека https://nodejs.org/api/ с прекрасной документацией.
А большое количество мусорных пакетов говорит юношеском максимализме аудитории, не более того. Понятия модульности и переиспользования возводятся в абсолют.
Хотя, дураки в сообществе - это наоборот хороший знак. Язык достаточно удачен, чтобы на нём смог писать даже идиот.
Это только люди, у которых программирование съело мозг, формируют взгляды на него как на занятие отборной элиты, где не должно быть ни дураков, ни представителей каких-то других профессий, кроме божественных программистов. Но снаружи этого манямирка в реальном мире находятся люди, которым нужна автоматизация их задач, и которым насрать, как там передаётся значение, по ссылке или нет, кто им будет владеть и чем виртуальный метод отличается от невиртуального. Главное - чтобы программа работала, приносила доход и для её обслуживания не надо было нанимать докторов хаскельных наук.
К примеру, ты хочешь сделать веб-студию, заниматься продвижением сайтов и маркетингом.
Очевидно что JavaScript для тебя неплохой выбор: ты сможешь быстро найти специалистов по созданию сайтов, да и свою голову можно будет освободить для более интересных вещеий, например для изучения маркетинга.
Совсем другое дело если ты, например, хочешь написать статический анализатор кода.
Делать это приятнее на каком-нить Ocamle, да и коммунити тебе предстоит найти совсем другое.
ахахаха
На самом деле JS прост и ебанут.
https://ideone.com/1jkccD
Полагаю, что субж загружен в страницу с ключом R/O, а попал он туда, ибо был в соответствующей секци бинарня
Кстати, а зачем там статик поставлен? Он же вроде вне фнукций имеет совсем другое значение (петухи будут видны только в этом фале), тут он бессмысленен.
У меня просто привычка все закрывать на автомате: я всегда в жабе все делаю private, final итд. В сисечке все const (что можно) и static (если речь идет о внешних символах)
У формата бинарника a.out, например, нет ридонли-секции. Там только три стандартные секции (код, данные и неинициализированные данные). Линкер может поместить константу либо в код (но тогда не будет защиты от выполнения), либо в данные (но тогда не будет защиты от записи). Обычно выбирают второе.
Тут небольшое расследование о форматах бинарников:
http://govnokod.ru/25359#comment458045
динамически бы точно не смогли, нету такого аби же
>а еслиб оно не было статик,
что можно было бы обратиться к нему?
Это ведь не функция
Моя спрашивать, можно-ли обращаться pitushki компилируюсь динмически, или же только статически?
а есть примеры, когда реально так делают*
http://govnokod.ru/25767#comment496654
А вот если объект мутабельный — всё будет окей. Именно поэтому я за «C(++)».
В Паскале модификатор const параметра функции принимает аргумент по ссылке, но запрещает явное изменение значения внутри функции. Да, ссылка — это синтаксический сахар, когда фактически передаётся указатель (без копирования данных), но выглядит, как будто передали данные. Проверяем:
https://ideone.com/SWpK67
Да, работает так же, как в сишке/крестах. Компилятор явно запретил внутри процедуры изменять значение roosters, но не запретил брать адрес и модифицировать косвенно. Какой багор )))
Компилируем, запускаем... Ничего не изменилось. Оказывается, в «Турбо Паскале» тупизированные константы (в отличие от нетупизированных) на самом деле являются инициализированными переменными. Отключаем совместимость с «Турбо Паскалем» директивой {$J-}. Компилируем, запускаем... В «Windows» падает от нарушения защиты, потому что компилятор поместил константу в секцию .rdata, закрытую от записи.
В «Ideone» же защита не сработала: https://ideone.com/pvoMYf
Видимо, та модификация компилятора, которая установлена в «Ideone», ридонли-секцию не создаёт.
И так:
* есть вариантные записи, но их можно наебать
* есть ренджи, но их можно наебать
* есть const, но и их можно наебать.
Знаете, я так могу и в Python и в Perl семантику описать
* Чтобы наебать ренджи, нужно компилировать с директивой $R-.
* const:
1. В параметре функции — да, легко наёбывается взятием указателя. Напрямую модифицировать компилятор всё-таки не даёт (уже на этапе компиляции запрещает присвоение).
2. Как типизированная константа — пофиксили во Фрипаскале, если при компиляции отключить совместимость с Турбопаскалем.
https://freepascal.org/docs-html/current/ref/refsu18.html
Для него рантайм проверяет, значение какого типа в данный момент хранится. К сожалению, он может хранить значения только из фиксированного набора типов (скалярные, включая плавающих питухов и перечисления, строки, указатели).
Как сейчас помню
* запись
* множество
* массив
* скаляр
https://freepascal.org/docs-html/current/ref/refsu20.html
А вот это уже не по-паскалевски, ибо статический анализатор для строчки V:=W.Application.Version; не работает. Это синтаксический сахар: она трансформируется в вызов API, которому передаётся строка 'Application.Version'.
Оказывается, «Irie Pascal» строго проверяет вариантные записи. Остальные реализации — да, можно наебать.
Так что рустеров своих ты тупо скопировал.
Проверь
А у меня слово «const». Оно отменяет копирование (как «var»), но при этом компилятор включает статический анализатор кода, запрещающий изменение значения.
А это в стандарте, или ты asm подсмотрел?
Икарус, как ты помнишь паскль? Ты на нем пишешь, или помнишь его с института?
зы; имеется ввиду const в сигнатуре функции.
Область модуля конечно была
http://www.pascal-central.com/docs/iso7185.pdf
Да, секция, открывающаяся словом const.
Типизированных констант в этом документе не нашёл, как и параметров-констант у функций.
const может и не было, но в tp 70 было ключ слово const.
Так вот реализация в TP имела даже не дыру, а парадные ворота: типизированные константы не были защищены от изменения. По факту это были переменные с начальным значением (они помещались в инициализированную часть секции, физически присутствующую в экзешнике, в отличие от переменных из секции var, которые были в той части, которая физически в экзешнике не присутствовала и создавалась во время загрузки).
Во Фрипаскале это пофиксили: там сделали возможность у var указывать начальное значение, а типизированные константы защитили от изменения. Но при этом добавили переключатель, включающий режим обратной совместимости.
https://i.postimg.cc/85WrpMf8/lal.png
Студент: если я покажу вам багу паскаля -- дадите мне зачет?
Препод: не может быть такого, паскаль -- безглючный язык
Студент
В TP, начиная с 4.0, не скомпилируется, потому что слово IMPLEMENTATION зарезервировали для модулей.
Это слово — расширение языка, придуманное «Борландом» в версии 4.0, когда добавили модульную систему.
Что не так?
Мне тут говорили, что в стандартном паскале модульцев не было, поэтому прога использующая идентификатор interface работала в стандартном и обсирается в турбированном и его последователях?
Я угандал?
По той же самой причине сишный код, содержащий переменные с именем «class», нельзя скомпилировать в «C++».
2. Добавим var — вернёт 20.
3. Добавим const:
Не компилируется:
2. Если я напишу
это будет константный указатель на питуха, или указатель на константного питуха?
Пушо у меня он отлично меняетсчя
t^ := 12;
зы: бля, как давно я не брал в руки шашку
пишу turbo.exe в dosbox, и мне снова 15 лет
Это константный указатель на питуха. Запрещено менять указатель, но не питуха.
хорошо, что 20 лет назад нам было на это похуй
В Си массив — это сахар над указателем. В Си модно было писать while(*p++ = *q++) и вообще использовать арифметику указателей, где только можно. Поэтому и задумались о защите объектов, на которые ссылаются указатели.
В Паскале же арифметики указателей нет. Можно, конечно, кастовать указатель в число, изменить и кастовать обратно в указатель. Можно использовать инкремент/декремент. Но так обычно не делают. В Паскале модно объявлять типы и делать всё через типы: массивы, записи и т. п. Заодно получим проверку границ индекса массива (которую в Си нужно делать вручную).
Возможно, по этой причине разработчики Паскаля (Вирт и разработчики более поздних реализаций) сразу об указателях на константного питуха не задумались.
точно сахар?
Сравни
char jaichko[42]; //выделит 42 чара на стеке
char jaichko*; //выделит указатель там же
А в сигнатуре функции не бывает. И в возвращаемом значении тоже.
Причем в сигнатуре можно написать, и ничего за это не будет
void foo(char petuh[]) {
}
короче, неконсистентное говно эта ваша сисшка
https://cdn1.ozone.ru/multimedia/c650/1004496212.jpg
Я помню, как охуел там от такого приема: ты ищешь что-то в массиве, и на каждом шаге проверяешь, что массив еще не кончился, и что в нем нет того, что ты ищещь.
Но ты можешь вставить искомый элемент в последний элемент массива, и элиминировать проверку на конец массива: ты всегда что-то найдешь, просто если ты нашел в самом конце, то по сути не нашел.
В те года это было реально круто
Если у тебя есть 10 байт памяти, то сделать в них стек очень легко, а как сделать в них очередь?
Вот у тебя заполнились 10 байт, и ты забрал из очереди 1 элемент. Очередь имеет свободное место с головы, но в хвост ее ничего не вставишь.
Казалось бы: можно подвинуть все на 1 байт, но нахуй двигать, если можно сделать кольцевой буфер, и указатель на место "вставки"? В итоге ты вставляешь в голову массива, но это как-бы "хвост"
страница 59
зы: смори, какой крутой блог
https://socket3.wordpress.com/
напрмиер вот
https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/
(@ перед from нужна как раз чтобы показать, что это идентификатор, т.к. в данном контексте это уже зарезервированное слово)
Говорят, в «PL/1» значков для отделения идентификаторов от ключевых слов не было. Такой код был валиден:
Собачка тут только для того, чтобы передать rvalue в функцию reset.