1. C++ / Говнокод #26040

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 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;
    }

    https://ideone.com/Xk9Ukg

    Нахуй так жить?

    Запостил: BJlADuMuPCKuu_nemyx, 22 Ноября 2019

    Комментарии (225) RSS

    • Теье не нра что конпелятор молча разрешает снять comst?
      Ответить
    • Даже с ключом -Стена ни одного ворнинга.
      Ответить
    • питушок, ты мало того, что сам явно снял конст, да к тому же сделал это сишным способом вместо плюсовово каста, что тебе не так?
      Ответить
      • Я должен был использовать злоебучий "static_cast<>"? Нахуй он нужен, если скобочки короче?
        И вообще, представь, что "asshole" писал не я. Я просто передал в функцию const.
        Ответить
        • Эзхол писал осёл: зачем он принял const, и изменил его?

          >скобочки короче
          ну ёбвашумамку, скобочки имеют мутную семантику (расщирение типа? снятие каста? трактовка тех же данных по другому?), а касты такой проблемы не имеют. Не нужно в крестах скобочек.

          Я тебе там ниже покушать принес
          Ответить
          • > зачем он принял const, и изменил его?
            это из разряда #define true false и т.п.
            Ответить
            • всё так.

              Удаление оттудава конст приводит к ошЫбке
              [q]
              prog.cpp:18:13: error: invalid conversion from ‘const Rooster*’ to ‘Rooster*’ [-fpermissive]
              [/q]

              Кстати, это ошибка же только в С++? в си это был бы варнинг?

              ну в любом случае, это не прошло бы незамеченным
              Ответить
              • Перевёл на «plain C»:
                #include <stdio.h>
                
                typedef struct Rooster_tag {
                   int id;
                } Rooster;
                
                
                void asshole(const Rooster* roosters) {
                    Rooster* r = roosters;
                    for (int i = 0; i < 3; i++) {
                        r[i].id = i + 1;
                    }
                }
                
                
                int main() {
                    Rooster roosters[3] = {{.id = 0}, {.id = 0}, {.id = 0}};
                    asshole(roosters);
                    for (int i = 0; i < 3; i++) {
                        printf("%d\n", roosters[i].id);
                    }
                	return 0;
                }


                https://ideone.com/v7XWm0

                Всего лишь ворнинг:
                a.c: In function 'asshole':
                a.c:9:18: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
                     Rooster* r = roosters;
                                  ^~~~~~~~
                Ответить
                • "Rooster_tag" писать не обязательно.
                  Ответить
                  • Привычка. Какие-то древние компиляторы ругались, когда структура безымянная, даже если следует тайпдеф.

                    Вот Dummy0001 (правильно написа́л его юзернейм?) любит повсюду писа́ть слово «struct». Вот ему Rooster_tag пригодится.

                    Перевёл на язык «Dummy0001»:
                    #include <stdio.h>
                    
                    struct Rooster_tag {
                       int id;
                    };
                    
                    
                    void asshole(const struct Rooster_tag* roosters) {
                        struct Rooster_tag* r = roosters;
                        for (int i = 0; i < 3; i++) {
                            r[i].id = i + 1;
                        }
                    }
                    
                    
                    int main() {
                        struct Rooster_tag roosters[3] = {{.id = 0}, {.id = 0}, {.id = 0}};
                        asshole(roosters);
                        for (int i = 0; i < 3; i++) {
                            printf("%d\n", roosters[i].id);
                        }
                    	return 0;
                    }

                    Ничего не забыл или надо ещё побольше слов «struct» напихать?
                    Ответить
                    • Именно поэтому я за "C++".
                      Ответить
                      • Верните на «Говнокод» Dummy0001. С ним были такие интересные холивары! Он повсюду пытался доказать, что тайпдефы не нужны.
                        Ответить
                        • Конечно не нужны. Я за "#define".
                          Ответить
                          • #define не нужен с тех пор, как привезли const и typedef
                            Ответить
                            • В сишке конст значит немного не то:
                              const int N = 100500;
                              Rooster roosters[N];
                              не сконпилица.
                              Ответить
                              • Именно поэтому я за «constexpr».
                                Ответить
                                • А в «C++20» обещают ещё «consteval»:
                                  https://en.cppreference.com/w/cpp/language/consteval

                                  Главное — не перепутать, где использовать «constexpr», а где «consteval»:
                                  consteval int sqr(int n) {
                                    return n*n;
                                  }
                                  constexpr int r = sqr(100);  // OK
                                   
                                  int x = 100;
                                  int r2 = sqr(x);  // Error: Call does not produce a constant
                                   
                                  consteval int sqrsqr(int n) {
                                    return sqr(sqr(n)); // Not a constant expression at this point, but OK
                                  }
                                   
                                  constexpr int dblsqr(int n) {
                                    return 2*sqr(n); // Error: Enclosing function is not consteval and sqr(n) is not a constant
                                  }

                                  Правда, простой и понятный язык?
                                  Ответить
                                  • consteval может выполняться только в константом контексте,
                                    constexpr может в любом.
                                    Отсюда нельзя consteval использовать от переменных, переданных в constexpr.
                                    Так же?
                                    Ответить
                                    • Точно.

                                      У них ещё и constinit есть:
                                      https://en.cppreference.com/w/cpp/language/constinit

                                      Это когда мы хотим убедиться, что начальное значение переменной является константой, чтобы оно попало в бинарник, но дальше мы значение переменной хотим изменять.
                                      Ответить
                                      • Какой бароп )))
                                        Ответить
                                        • Итак, если я правильно понял, constexpr разрешает использовать выражение в константном контексте, но не зашкваривает его. Мы это выражение можем использовать и в константном контексте (тогда оно вычисляется на этапе компиляции), и в неконстантном (тогда оно вычисляется в рантайме).

                                          Таким образом, constexpr ещё не гарантирует, что оно всегда будет константой. Это только хинт для компилятора, что тут можно оптимизировать.

                                          consteval же гарантирует, что выражение будет вычисляться на этапе компиляции, поэтому зашкваривает его, и в неконстантном контексте его уже вызвать нельзя.

                                          Если мы зашкварили функцию атрибутом consteval, то для того, чтобы такой же код использовать с переменным аргументом, его придётся продублировать (под другим именем).

                                          constinit же придумали для привередливых, которые хотят убедиться, что начальное значение будет посчитано на этапе компиляции и попадёт в секцию данных.

                                          Ничего не перепутал?
                                          Ответить
                                          • Сколько питушни нагородили! Получается уже 4 класса сущностей, куча времени на обучение тонкостей и боль при переводе функций из разряда обычных в какой-нибудь другой разряд.

                                            Сделали бы уже простую двухпроходную схему.
                                            1. Везде, где нужна константа времени компиляции, выражение заключается в вызов const
                                            2. При компиляции программа запускается, значения внутри const берутся из памяти и сохраняются для вставки в скомпилированную версию
                                            3. Для сложных кобенаций указателей сделать operator char* + constructor (char*) или отдельные операторы сериализации-десериализации (вообще, стандартные они бы пригодились и без этого). Компилятор может соптимизировать десериализатор, если что.

                                            Всё. Не нужно наворачивать говна, сильно усложнять компилятор и стандарт.
                                            Ответить
                                            • Все помнят, что само слово «const» в «C++» может использоваться не только в описании типа, но и в описании методов класса, где оно имеет особое значение?
                                              https://en.cppreference.com/w/cpp/language/member_functions#const-.2C_volatile-.2C_and_ref-qualified_member_functions

                                              int operator[](int idx) const {
                                                                        // this has type const Array*
                                                      return data[idx]; // transformed to (*this).data[idx];
                                                  }


                                              Кстати, что оно там означает?
                                              Ответить
                                              • Все, кто пишет на C++ что-то серьёзное, помнят.

                                                > Кстати, что оно там означает?
                                                Сам себе ответил же:
                                                > this has type const Array*
                                                Ответить
                                                • А ещё в C++ можно создать константный указатель на неконстантный указатель на константного питуха и неконстантный указатель на константный указатель на неконстантного питуха.
                                                  Ответить
                                                  • Как-то так должен начинаться рекламный ролик про typedef.
                                                    Ответить
                                                  • Настоящим царям для указателей вполне достаточно void *, char * и явных кастов во всякую другую хуйню
                                                    Ответить
                                                    • Действительно, const придумали для анскиллябр, которые сами себе не доверяют.
                                                      Ответить
                                              • Оно означаает, что этот метод не меняет состояние объекта

                                                Я же недавно рассказывал, что у жабоебов и шапеев этого нету, и потому ни вынуждены плодить интерфейсы (так им и надо, анскилябрам заедушным)
                                                Ответить
                                                • В «PHP» этого тоже нету. Именно поэтому я за «PHP».
                                                  Ответить
                                              • Основное назначение такого const — реализация иммутабельных методов, которые можно дёргать у константного объекта/ссылки:
                                                struct Kurochka {
                                                    void snestiYaichko()
                                                    {
                                                        yaichki--;
                                                        puts("Kok!\n");
                                                    }
                                                
                                                    void kukareknut() const
                                                    {
                                                        puts("Ja ne petuh, ya kuritsa!\n");
                                                    }
                                                
                                                    int yaichki = 10;
                                                };
                                                // ...
                                                const Kurochka kurochka{};
                                                kurochka.kukareknut();
                                                kurochka.snestiYaichko();  // error

                                                А ещё методы можно перегружать по константности:
                                                struct Kurochka {
                                                    void kukareknut()
                                                    {
                                                        yaichki--;
                                                        puts("*snesla yaichko ot vozmuscheniya*");
                                                    }
                                                
                                                    void kukareknut() const
                                                    {
                                                        puts("Ja ne petuh, ya kurochka!");
                                                    }
                                                
                                                    int yaichki = 10;
                                                };
                                                // ...
                                                Kurochka kurochkaMutable{};
                                                const Kurochka kurochkaImmutable{};
                                                kurochkaMutable.kukareknut();    // *snesla yaichko ot vozmuscheniya*
                                                kurochkaImmutable.kukareknut();  // Ja ne petuh, ya kurochka!

                                                Хороший пример использования такого подхода — реализация begin()/end() в итераторах. Это очень удобно тем, что не нужно беспокоиться о константности ссылки, «for (auto it = vec.begin();...)» сработает и для «T &», и для «const T &», причём во втором случае it будет константным итератором.

                                                Именно поэтому…
                                                Ответить
                                                • > А ещё методы можно перегружать по константности:


                                                  const Petuh h;
                                                  h.koko();

                                                  и
                                                  Petuh h;
                                                  h.koko();

                                                  это РАЗНЫЕ методы?!


                                                  Какой С++!!
                                                  Ответить
                                                  • Да, если они перегружены. Если не-const метода нет — вызывается только константный.
                                                    Ответить
                                                    • сложное какое это ваше програмирование

                                                      буду курьером
                                                      Ответить
                                                      • Именно поэтому я за «курьеров».
                                                        Ответить
                                                        • У меня был роботикс курьер. Спортстер тоже был, но курьер был круче. ATI7, чувак.

                                                          А у тебя был?
                                                          Ответить
                                                          • Колготки Pretty Polly ATI7 купить в интернет-магазине
                                                            www.pаwliniа.ru › collection › pretty-polly › product › kolgotki-pretty-po...
                                                            мягкие колготки из микрофибры 60 den c классическим рисунком.
                                                            Ответить
                                              • /del
                                                Ответить
                              • Фууу. Анскильная сишка.
                                Ответить
                                • "Используя данный паяльный флюс, не следует забывать о том, что это химикат и работа с ним требует соблюдения правил безопасности. Во время лужения следует беречь слизистые желудка и глаз. Работа осуществляется при помощи кисточки, которая прилагается к комплекту ЛТИ-120. В случае если паяльный флюс попал на кожу, пораженные участки следует промыть большим количеством воды с использованием мыла."
                                  Ответить
                                  • При работе ты дышишь. Всегда.
                                    Если пары жидкости растворимы, они осаждаются на слизистых и в дальнейшем проникают в слюну, которая может проглатываться, кроме того, всасывание происходит на всей поверхности пищеварительной трубки, начиная от полости рта и кончая в толстой кишкой.

                                    Именно поэтому работать с химикатами на голодный желудок гораздо опаснее, чем на сытый.
                                    Ответить
                              • ахахаха
                                в плюсах копилится, в сишке -- нет

                                почему?
                                Ответить
                                • В сишке const — это не константа, а переменная, защищённая от изменения (смешно, да?). Вроде как оставили лазейку для того, чтобы в качестве начального значения можно было использовать произвольное выражение, а не только константу.

                                  Чтобы объявить обычный массив (не динамический!), в качестве его размера нужно задать чистую константу.
                                  Ответить
                                  • Для VLA небось не нужно?

                                    но VLA бывает только автоматический, небось, смысли на стеке
                                    Ответить
                                    • А с VLA всё работает. Этот код компилируется в чистой сишке:
                                      void pituh() {
                                          const int N = 100500;
                                          Rooster roosters[N];
                                      }

                                      Тут roosters[N] будут созданы в стеке тупо декрементом указателя на вершину. На этапе компиляции значение N знать не нужно.

                                      А вот в глобальном контексте в «Plain C» не компилируется.
                                      Ответить
                                    • > VLA

                                      Это сокращение "Владимир"?
                                      Ответить
                                      • Варианты:
                                        • Внутреннее обозначение аэропорта Владикавказа.
                                        • Великая ложа Англии.
                                        • Very large array = сверхбольшая антенная решётка (радиотелескоп).
                                        Ответить
                                        • >Владикавказа
                                          надо бы туда слетать, выпилить одного рака
                                          Ответить
                                          • Слетай, там /fxd тебя накормят сыром поздалупным и с собой дадут.
                                            Ответить
                                  • > В сишке const — это не константа, а переменная, защищённая от изменения

                                    В ++ тоже

                                    int petya = 5;
                                    const int petr = petya;
                                    Ответить
                                • #include <stdio.h>
                                  
                                  const int N = 100;
                                  int * huroz = &N;
                                  
                                  int main() {
                                      *huroz = 265;
                                      printf("%d\n", N);
                                      return 0;
                                  }


                                  Падает во время исполнения, потому что линкер поместил N в секцию .rdata. На платформе же без секции .rdata значение N будет подменено.
                                  Ответить
                                  • Надо быть полным додиком, чтобы править константу.


                                    Ответить
                        • Дамми еще и в перле рубил, я бы с ним попиздел
                          Ответить
                    • Кстати, есть такой срач:

                      MS: надо всегда делать typedef, чтобы никогда не писить struct. В Win32API ВСЁ через typedef.
                      Unix: надо всегда делать struct.

                      А ты за кого?
                      Ответить
                      • Кстати, а в чем тут смысл униксого подхода?
                        Ответить
                    • ахахах, пустая ослиная нора)))
                      Ответить
                • > Всего лишь ворнинг

                  Rooster* r = (Rooster*) roosters;

                  /fxd


                  Но спасибо хоть на такое ворнинг
                  Ответить
                  • В крестах с таким же кастом тоже без ворнинга. Вообще тихо.

                    А вот без каста в крестах будет ошибка.
                    Ответить
                    • Именно поэтому я за "PHP".
                      Ответить
                      • Кстати, «PHP» не позволит в функцию передать по ссылке константу:
                        PHP Fatal error:  Only variables can be passed by reference
                        Ответить
                        • ИМенно по этому я за "Perl"
                          use strict;
                          use warnings;
                          
                          
                          my $a = \123;
                          
                          $$a = 12; # вот тут упадет Modification of a read-only value attempted at
                          Ответить
                          • А в «PHP» нет оператора бэкслэш. Там вообще нельзя брать адреса, можно только ссылки, но ссылки тупо являются синонимами. Зато во многих местах можно лазить по массиву всех переменных, всех констант, всех функций, всех классов.

                            <?php
                            
                            $a = 123;
                            
                            $$a = 12; // Эта строка создаст переменную с именем 123.
                            // Обратиться к ней как $123 будет нельзя, это синтаксическая ошибка.
                            // Но её видно в массиве глобальных переменных как $GLOBALS[123]
                            // и, внезапно, как ${123}. Да, фигурные скобки позволяют обращаться
                            // к некорректно названным переменным:
                            var_dump(${123});
                            Ответить
                            • слеш в Perl тоже по сути берет reference (во всяком случае Волл так ее называет), и так как там нет указательной арифметики, я все таки считаю это ссылкой.

                              То, про что говоришь ты, там тоже можно
                              my $a = "myvar";
                              $myvar = "Q";
                              ${$a} = "S";
                              print $myvar; #S


                              Это называется "мягкая ссылка" (а через бекслеш -- жесткая)

                              ps
                              our $a = "myvar";
                              $myvar = "Q";
                              ${$a} = "S";
                              print ${*myvar{'SCALAR'}}; #S


                              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)
                                  Ответить
                                  • Сортировка разве обязана гарантировать стабильность? Если это, конечно, не std::stable_sort
                                    Ответить
                                    • stable_sort — это чтобы сортировать табуны лошадей?
                                      Ответить
                                      • Да. Есть ещё std::chicken_sort
                                        Ответить
                                      • Friend of mine once was hospitalized with a dozen of toy horses in his ass.

                                        Doctor described his condition as stable
                                        Ответить
                                        • https://en.wikipedia.org/wiki/List_of_animal_names

                                          Pack — это собачья стая.
                                          School — это косяк рыб.
                                          Congress — это стая бабуинов.
                                          Pod и flock — это птичья стая.
                                          Float — стая крокодилов.
                                          Safe — утиная стая.
                                          Array — стая ежей.
                                          Host — колония кузнечиков.
                                          Committee — стая мангустов.
                                          Parliament — совиная стая.
                                          Cluster — колония пауков.
                                          Ответить
                                          • pile of poo: конференция php разработчиков
                                            Ответить
                                            • Да эти хуемрази на свою конференцию даже ни одну бабу не пригласили.
                                              Ответить
                                              • Ты про немецкую конфу?
                                                Да и хуй с ними.

                                                Швейк знал двух Фердинандов:
                                                Один служит у фармацевта Пруши. Как-то раз по ошибке он выпил у него бутылку жидкости для ращения волос; а еще есть Фердинанд Кокошка, тот, что собирает собачье дерьмо. Обоих ни чуточки не жалко.
                                                Ответить
                                          • У лошадей это будет табун
                                            У рыб это будет косяк(с)
                                            Ответить
                                    • Стабильная сортировка гарантирует стабльность
                                      Нестабльная -- не гарантирует

                                      Капитан
                                      Ответить
                                      • Вопрос был "Для примитивов и для объектов используются разные алгоритмы сортировки, почему?", а не "Для примитивов и для объектов используются разные алгоритмы стабильной сортировки, почему?"

                                        Откуда мне знать что требуется стабильная сортировка?
                                        Ответить
                                        • Кажется, этот вопрос обсуждался во многих книгах про джаву.

                                          Для примитивов используется qsort: он может быть быстрее, но нестабилен. Для объектов merge sort.
                                          Впрочем, для последних джав они могли это поменять
                                          Ответить
                                  • Да, ну и как сделать из нестабильной сортировки стабильную - и у меня даже спрашивали )
                                    Ответить
                                    • У нас обычно просят рассказать про merge sort vs quick sort.

                                      Бывают правда чуваки, которые кроме пузырька ничего не помнят наизусть
                                      Ответить
                              • Где ты пистоне примитивы видел? Там одни объеткы и всё по ссылке (на обект) пиридается. Просто многие немутабельны и ещё нет ссылок именно на переменные (которые все хранят ссыки на объекты).
                                Ответить
                                • >Там одни объеткы и всё по ссылке (на обект) пиридается
                                  даже число 4?
                                  Ответить
                                  • Представь себе, а иначе зачем ещё хранить кеш маленьких чисел?

                                    Можешь посмотреть реализацию:
                                    https://github.com/python/cpython/blob/master/Objects/longobject.c
                                    Ответить
                                    • И правда, кеш малышей
                                      PyObject *v = (PyObject*)small_ints[ival + NSMALLNEGINTS];


                                      Видимо это сделано для единнообразности: работать с большими и маленькими числами удобнее одинаково, даже если мы и теряем немного времени на ненужной (с точки зрения байтойоба) операции, ведь мощность указательного типа на современных архитектурах может превышать мощность типа, необходимого для хранения небольших чисел.

                                      Кажется, в Ruby раньше для больших и малых чисел использовались разные типы (с автоматическим превращением, разумеется), но возможно что это уже не так.
                                      Ответить
                                      • А его можно испортить, как в «Жабе», чтобы 2+2 равнялось пяти?
                                        Ответить
                                        • Никогда не пробовал портить ничего в питоне.

                                          Приятнее всего портить что-то в Ruby, там для этого есть все возможности
                                          class Fixnum 
                                              def +(obj) 
                                                  42 
                                              end
                                          end
                                          
                                          p 2 + 2 # 42


                                          В Perl так же присутствуют мощные инструменты для портинья
                                          use overload;
                                          BEGIN {
                                          	sub foo {
                                          		42;
                                          	}
                                          	overload::constant ( integer => \&foo);
                                          }
                                          
                                          print 2 + 2; # 84
                                          Ответить
                                          • Рубиновый код именно числа не портит, ты просто перегрузил оператор.

                                            А вот с перлом интересно, для чего изначально было придумано overload::constant?
                                            Ответить
                                            • например чтобы
                                              https://metacpan.org/pod/overload#Copy-Constructor
                                              Ответить
                                          • Оказывается, в Яибу нет операторов ++ и --. Совсем нет. И даже нет возможности их перегрузить.

                                            Юкихиро Мацумото сказал, что они не нужны.
                                            Ответить
                                            • Держи нас в курсе, если в "Яибу" что-нибудь появится.
                                              Ответить
                                            • Ты не поверш, но в пистоне их тоже нету

                                              Питонисты просто пишут

                                              foo += 1
                                              и текут
                                              Ответить
                                        • Не знаю, ссылки на кеш из питана вроде нет, но можно получить адресс обеъекта (id() это вроде он и есть). Только вот в питоне я умею только читать по адресу в памяти, а писать не умею. В питоне всё это онально огорожено.
                                          Ответить
                              • Учитывая, что C это по сути подмножество ObjC, я не понимаю, что ты имел в виду, когда их противопоставлял.
                                Ответить
                                • вероятно, он имел ввиду передачу объектов, коие в объектой сишке всегда управляются через указатель, и (соответственно) никогда не копируются при вызове
                                  Ответить
                                  • Я прост не понял, почему мы сравниваем с С/C++. Имеет смысл сначала сравнить как раз сами C и C++ между собой.

                                    Про объекты в Obj C ты правильно пишешь, но вот остальные типы данных там один в один сишные и ведут себя ЕМНИП как сишные. Думаю, что структуры сишные в Obj C методы тоже можно передавать всеми известными способами, но проверять лень

                                    В этом смысле Свифт другой: там есть чёткое разделение на value и reference прямо на уровне языка. Как по мне, то в прикладухе такая ясная семантика важнее, чем некая условная гибкость
                                    Ответить
                                    • Мне тоже кажется, что обычные сишные сущности (structы и скалярные типы) работают в ObjC так же, как и в си.

                                      Вероятно, речь тут о том, что в С и С++ программист сам решает, как ему передавать объект: может скопировать, а может передать ссылку или указатель, причем передавать указатель можно даже для объекта на стеке (и разумеется всегда для объекта на куче, так как доступа к нему кроме как через указатель нет).
                                      Речь конечно о ситуации, когда программист имеет контроль и над вызываемой функцией тоже.

                                      ObjCные же объекты всегда располагаются на куче (кроме блоков, кажется, но и те копируются при передаче наружу) и у программиста нету выбора где из создать (и, соответственно, как их передать).

                                      Разделение на value и reference мне нравится.
                                      А можно передать по ссылке value object?

                                      Я спрашиваю, потому что например в C# можно (хотя по умолчанию он конечно скопируется) а например в Java -- нельзя
                                      Ответить
                                      • > А можно передать по ссылке value object?
                                        - формально да. Фактически происходит двойное копирование.

                                        https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID545

                                        Но, честно говоря, не помню даже, когда бы писал функции с inout
                                        Ответить
                          • Где здесь use constant?
                            Ответить
                  • Кстати, жабо/котлин, C# и (вероятно)ObjC тут соснут: в них нет возможности сказать, что объект неизменяем.

                    Придется делать спец. интерфейс, и указывать его в сигнатуре функции.

                    interface PetuhRO {
                    int getIq();
                    }
                    class Petuh implements PetuhRO{
                    void setIq(int iq){..}
                    @Override
                    int getIq(){..}
                    }
                    
                    //..
                    void assHole(PetuhRO petuh) {
                    petuh.//можем только getIq();
                    }


                    в С++ это решается const, именно потому я за
                    Ответить
                    • Лоол. Так реально делают?
                      Вообще, как завещал [забыл как его фамилия], геттеры и сеттеры нинужны.
                      Ответить
                      • Ну а как бы ты еще сделал?

                        В python и ruby так конечно не делают (там джентельменское соглашение), а в java очень даже.
                        В C# хотя-бы есть сахар для этого.

                        В С++ я бы просто пометил аксессор как конст, и потек
                        Ответить
                • > Всего лишь ворнинг
                  Именно поэтому я за "-pedantic-errors".
                  Ответить
          • А зачем конпилер даёт это сделать?
            Ответить
            • кууик
              нууу
              эээ
              ммм

              Это же си, чувак. Тут можно сделать всё, что угодно.
              Ты можешь взять число 1234 и скастить его в указатель на массив интов, и что-то там поправить по этому адресу с известными последствиями.

              Хочешь, чтоб такое вообще не компилировалось?
              Ответить
          • >> скобочки имеют мутную семантику

            Так точно. Список того, что делают скобочки, очень длинный, и в уме это просчитать трудно, обязательно какой-нибудь из вариантов упустишь из виду. В крестах лучше более явные касты.
            Ответить
            • Скобочки — это «оператор javascript». Скасти что угодно во что угодно* и получи какую-нибудь хуйню. Может быть даже она будет полезна.
              *почти
              Ответить
              • С новым годом тоскливый родной Бессмертный одинокий умный злой преданный изобретательный больной счастливый говнокод.
                Ответить
          • for (int i = 0; i < (int) roosters.size(); i++)

            Имею привычку не использовать «unsigned» при итерации.
            Также имею привычку при сравнении «unsigned» и «int» приводить к «int».
            Ответить
            • зачем нужен инт, когда есть _t?
              Ответить
            • С тех пор, как поглядел на интовые багры — имею привычку вообще никогда не использовать знаковые типы, за исключением случаев, когда требуется обработать отрицательное число.
              И я за «size_t».
              Ответить
              • for (i = size - 1; i >= 0; i--)


                Выкуси.
                Ответить
                • Не нужен.
                  const char *str = "Hello";
                  size_t size = strlen(str);
                  while (size--) {
                      putchar(str[size]);
                  }  // olleH

                  std::string str = "Hello";
                  for (auto it = str.rbegin(); it != str.rend(); ++it) {
                      std::cout << *it;
                  }  // olleH
                  Ответить
    • питушок, я тебе более страшную хуйню принес
      #include <iostream>
      using namespace std;
      
      struct Rooster {
         int id = 0;
      };
      
      static const Rooster petushok[3];
      
      void asshole(const Rooster* roosters) {
          Rooster* r = const_cast<Rooster*>(roosters);
          for (int i = 0; i < 3; i++) {
              r[i].id = i + 1;
          }
      }
      
      
      int main() {
          asshole(petushok);
          for (int i = 0; i < 3; i++) {
              printf("%d\n", petushok[i].id);
          }
      	return 0;
      }

      угадай, что тут будет
      Ответить
      • Предположу, что компилятор по другому соптимизировал, и выкинул нахуй вызов asshole, и остались нули. Сейчас запущу...
        Ответить
        • ну-ка запусти, расскажешь потом:)
          Ответить
          • Именно поэтому я за реальный режим.
            Ответить
            • вообще был разве конст в borland c?
              Ответить
            • Рустер, ты пробовал писать свою ОС проги, которые выполняются без ОС?
              Ответить
              • Я как-то написал прогу, которая влезла в MBR, и вывела "Hello". Не знаю, считается-ли это.
                Ответить
                • На чём писал, кстати? На ассемблере, в мышиных котах или на ЯВУ?
                  Ответить
                  • на масме

                    Я как-то углублялся в асм под реальный режим, и это была одна из моих попыток в нем прокачаться.
                    Ответить
                • Я как-то пытался уместить форт-системку в бут-сектор, но когда она стала способна исполнять введённый код она уже даже в 2 сектора не умещалась (((

                  Это было года 3-4 назад, я только учил асм, сейчас тот код мне кажется глупым. Может быть если использовать байт-код и вынести заголовки отдельно и уместится, но я стал гораздо более ленивее.

                  Кстати, я тогда не ладил с родителями и мне не разрешали садится за комп, я написал эту системку на смартфоне и собирал и отлаживал её также на смарте в досбоксе )))
                  Ответить
                  • Кококококой хардкор )))
                    Ответить
                  • У меня где-то 8кб получалось на базовую систему на 32-битном асме. Жаль, что код куда-то проебался.
                    Ответить
                    • Какой анскилл )))
                      Ответить
                    • Standalone под x86? Наверное неплохо.

                      Кстати об ОС и маленьких программах, когда-то на форуме фасма проводилась специальная олимпиада на 512-батную ОС, в посылках были всякие аналоноги досовских дебагеров и тетрисы, а первое место заняла многозадачная Nano OS да ещё и с тремя демо-приложениями для теста.

                      Тут есть архив с посылками:
                      http://board.flatassembler.net/topic.php?t=2164&postdays=0&postorder=as c&start=140

                      Чувствую себя анскилляброй(
                      Ответить
                      • 78 килобайт. Не мега и не гига. Архив из 12 операционок. Какой скилл )))
                        Ответить
                        • Причём с сорцами. И в сорцах ничего необычного нет, ждешь увидеть там кучи всяких хаков, повторное использование цепочек кода, полиморфный код и т.п., а там самый обычный ассемблерный подпрограммный код. Я даже немного разочаровался.
                          Ответить
                          • То-есть вполне можно без всяких хаков писать полезные программы, которые весят 10 килобайт.

                            Почему, например, у меня одна папка node_modules весит 8,9 мегабайт тогда?

                            Может, как-то неправильно мы программируем компьютеры?
                            Ответить
                            • Потому что в node_modules один и тот же фрагмент кода повторяется 100500 раз, ибо NIH.
                              Ответить
                            • Посмотрим, чем забит npm:
                              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 и языка в целом.

                                JS был создан за пару недель без какого-либо глубокого анализа, и потому люди используют внешние пакеты для провери на is_null.

                                В других языках такой проблемы нет
                                Ответить
                                • Вот весь код устанавливаемого модуля:
                                  module.exports = isNull;
                                  
                                  
                                  function isNull(value) {
                                      return value === null;
                                  }


                                  К нему прилагаются юнит-тесты, метаданные пакета, Gruntfile.js, .travis.yml и ещё какая-то поебень.
                                  Ответить
                                  • Допустим, вам нужно будет проверить, что некоторая строчка содержит фразу 'Сергиев Посад'.

                                    Вполне может вознинуть такая задача в реальном приложении.

                                    На этот случай я советую воспользоваться моим модулем. Модудь распостраняется по GPL, то-есть совершенно бесплатен.

                                    module.exports = isSergievPosad;
                                    
                                    
                                    function isSergievPosad(value) {
                                        return value === isSergievPosad;
                                    }


                                    В настоящее время к выпуску готовится модуль isNotSergievPosad, обладающий схожим функционалом.


                                    Кроме шуток: они там все ненормальные чтоли?
                                    Ответить
                                    • У тебя опечатка. Выпустил патч для твоего модуля:
                                      -     return value === isSergievPosad;
                                      +     return value === "Сергиев Посад";
                                      Ответить
                                      • Спасибо, будет исправлено в версии 1.1

                                        А тест есть?
                                        Ответить
                                        • var tape = require("tape"),
                                              isSergievPosad = require("../src/index");
                                          
                                          
                                          tape("isSergievPosad(value) should return true when the value is a Сергиев Посад", function(assert) {
                                              assert.equal(isSergievPosad(undefined), false);
                                              assert.equal(isSergievPosad({}), false);
                                              assert.equal(isSergievPosad([]), false);
                                              assert.equal(isSergievPosad(""), false);
                                              assert.equal(isSergievPosad(/./), false);
                                              assert.equal(isSergievPosad(0), false);
                                              assert.equal(isSergievPosad(null), false);
                                              assert.equal(isSergievPosad(function noop() {}), false);
                                          
                                              assert.equal(isSergievPosad("Cергиев Посад"), true);
                                          
                                              assert.end();
                                          });
                                          Ответить
                                • Хейтер жс плюсанул. Так и рождаются предрассудки. JS - не большее говно, чем C++. Но есть отличие: с C++ надо настолько долго пердолиться, чтобы что-то внятное написать, что в мире C++ есть либо те, кто ещё не знает этот язык и не может о нём судить, либо те, кто провёл с ним столько времени, что его мозг свыкся с происходящим и уже получает удовольствие. JS же прост и понятен, ему не посвящается столько времени, не формируется синдром утёнка.

                                  NPM работает на пользу Node.js, где есть своя удобная стандартная библиотека https://nodejs.org/api/ с прекрасной документацией.

                                  А большое количество мусорных пакетов говорит юношеском максимализме аудитории, не более того. Понятия модульности и переиспользования возводятся в абсолют.
                                  Ответить
                                  • У С++ все же несколько меньшее количество дураков в коммунити, потому в целом там всё не так плохо, хотя конечно зоопарк там тоже тот еще
                                    Ответить
                                    • Да, это верно.

                                      Хотя, дураки в сообществе - это наоборот хороший знак. Язык достаточно удачен, чтобы на нём смог писать даже идиот.

                                      Это только люди, у которых программирование съело мозг, формируют взгляды на него как на занятие отборной элиты, где не должно быть ни дураков, ни представителей каких-то других профессий, кроме божественных программистов. Но снаружи этого манямирка в реальном мире находятся люди, которым нужна автоматизация их задач, и которым насрать, как там передаётся значение, по ссылке или нет, кто им будет владеть и чем виртуальный метод отличается от невиртуального. Главное - чтобы программа работала, приносила доход и для её обслуживания не надо было нанимать докторов хаскельных наук.
                                      Ответить
                                      • Ну должен сказать, что читать код, написанный непрограммистами - задача не для слабых нервов. Но про элиту несут хуйню в основном таки людишки, которым надо попонтоваться. Про докторов волнует или работодателя, который за это платит, или проггеров, которым не платят за понты, а платят за результат (в т.ч. когда пишешь для себя).
                                        Ответить
                                      • Всё зависит от области твоих интересов.

                                        К примеру, ты хочешь сделать веб-студию, заниматься продвижением сайтов и маркетингом.

                                        Очевидно что JavaScript для тебя неплохой выбор: ты сможешь быстро найти специалистов по созданию сайтов, да и свою голову можно будет освободить для более интересных вещеий, например для изучения маркетинга.

                                        Совсем другое дело если ты, например, хочешь написать статический анализатор кода.
                                        Делать это приятнее на каком-нить Ocamle, да и коммунити тебе предстоит найти совсем другое.
                                        Ответить
                                  • >JS же прост и понятен
                                    ахахаха
                                    Ответить
                                    • Если не использовать "prototype" и "this". C++ тоже прост и понятен, если не использовать метушню.
                                      Ответить
                                      • В «PHP» нет ни «ргототуре», ни «метушни». Именно поэтому я за «PHP».
                                        Ответить
                                    • Ну, он в первом прав.
                                      На самом деле JS прост и ебанут.
                                      Ответить
                      • а сколько весил qnx?
                        Ответить
                  • Какой скилл )))
                    Ответить
              • Форт считается за ОС?
                Ответить
          • "Ошибка выполнения"
            https://ideone.com/1jkccD
            Ответить
            • да, у меня тоже сигфолт
              Ответить
              • Почему сегфолт, кстати? Память принадлежит моей же программе.
                Ответить
                • наверное, надо смотреть дамп или выхлоп асемблера

                  Полагаю, что субж загружен в страницу с ключом R/O, а попал он туда, ибо был в соответствующей секци бинарня
                  Ответить
                  • Да, скорее всего он питухов сунул в ридонли секцию.

                    Кстати, а зачем там статик поставлен? Он же вроде вне фнукций имеет совсем другое значение (петухи будут видны только в этом фале), тут он бессмысленен.
                    Ответить
                    • Не зачем совершенно, storage class у всех внешних символов разумеется статический.

                      У меня просто привычка все закрывать на автомате: я всегда в жабе все делаю private, final итд. В сисечке все const (что можно) и static (если речь идет о внешних символах)
                      Ответить
                    • Причём тут повезло, что ридонли-секция была, поэтому мы заметили ошибку.

                      У формата бинарника a.out, например, нет ридонли-секции. Там только три стандартные секции (код, данные и неинициализированные данные). Линкер может поместить константу либо в код (но тогда не будет защиты от выполнения), либо в данные (но тогда не будет защиты от записи). Обычно выбирают второе.

                      Тут небольшое расследование о форматах бинарников:
                      http://govnokod.ru/25359#comment458045
                      Ответить
                    • Кстати, а еслиб оно не было статик, разве могли бы другие объектные файлы с ним слинковаться пусть и статически?

                      динамически бы точно не смогли, нету такого аби же
                      Ответить
                      • Какие другие объектные фалы? static значит что питушки видны только в этом файле и не видны снаружи
                        Ответить
                        • я же пишу
                          >а еслиб оно не было статик,
                          что можно было бы обратиться к нему?
                          Это ведь не функция
                          Ответить
                          • А, я понял о чем твоя спрашивает. Если бы оно не было статик, то в другом фале можно написать extern Rooster pitushki и обращаться. Но в тестовой программке из одного файла статик явно бесполезне.
                            Ответить
                            • Умный питуха, моя понял

                              Моя спрашивать, можно-ли обращаться pitushki компилируюсь динмически, или же только статически?
                              Ответить
                              • Да линкерам похуй на тип символов же. Они тупо по именам линкуют. Что статически что динамически.
                                Ответить
                                • ты хочешь сказать, то я могу сделать .dll или .so, которая экспортирует массив, а не функцию?
                                  Ответить
                                  • Вай нот?
                                    Ответить
                                    • охуясе

                                      а есть примеры, когда реально так делают*
                                      Ответить
                                      • Не видел. Ну разве что errno, но оно уже давно не переменная.
                                        Ответить
                                        • Я в каком-то треде по-моему что-то подобное спрашивал. Я там ещё написал сошку, печатающую строку, и исполняемый файл который её экспортирует, а main находится именно в сошке. Правда я не осилил выпилить дефолтный стартовый код из исполняемого файла.
                                          Ответить
      • UB. Откастить конст у ссылки можно, но если объект, на которую она указывает, объявлен константным — при попытке доступа будет пиздец.
        А вот если объект мутабельный — всё будет окей. Именно поэтому я за «C(++)».
        Ответить
    • А теперь посмотрим, как сделали в других ЯП.

      В Паскале модификатор const параметра функции принимает аргумент по ссылке, но запрещает явное изменение значения внутри функции. Да, ссылка — это синтаксический сахар, когда фактически передаётся указатель (без копирования данных), но выглядит, как будто передали данные. Проверяем:
      type
        Rooster = record
         id: integer;
        end;
        RoosterArray = array[0..2] of Rooster;
      
      procedure asshole(const roosters: array of Rooster);
        var
          r: ^RoosterArray;
          i: integer;
        begin
          r := @roosters;
          for i := 0 to 2 do r^[i].id := i + 1
        end;
      
      var
        roosters: RoosterArray;
        i: integer;
      begin
        for i := 0 to 2 do roosters[i].id := 0;
        asshole(roosters);
        for i := 0 to 2 do Writeln(roosters[i].id)
      end.


      https://ideone.com/SWpK67

      Да, работает так же, как в сишке/крестах. Компилятор явно запретил внутри процедуры изменять значение roosters, но не запретил брать адрес и модифицировать косвенно. Какой багор )))
      Ответить
      • Модифицируем: объявим в глобальном контексте roosters не как переменную, а как типизированную константу:
        type
          Rooster = record
           id: integer;
          end;
          RoosterArray = array[0..2] of Rooster;
        
        procedure asshole(const roosters: array of Rooster);
          var
            r: ^RoosterArray;
            i: integer;
          begin
            r := @roosters;
            for i := 0 to 2 do r^[i].id := i + 1
          end;
        
        const
          roosters: RoosterArray = ((id: 0), (id: 0), (id: 0));
        var
          i: integer;
        begin
          asshole(roosters);
          for i := 0 to 2 do Writeln(roosters[i].id)
        end.


        Компилируем, запускаем... Ничего не изменилось. Оказывается, в «Турбо Паскале» тупизированные константы (в отличие от нетупизированных) на самом деле являются инициализированными переменными. Отключаем совместимость с «Турбо Паскалем» директивой {$J-}. Компилируем, запускаем... В «Windows» падает от нарушения защиты, потому что компилятор поместил константу в секцию .rdata, закрытую от записи.

        В «Ideone» же защита не сработала: https://ideone.com/pvoMYf
        Видимо, та модификация компилятора, которая установлена в «Ideone», ридонли-секцию не создаёт.
        Ответить
        • Ну то-есть паскакаль опять обосрался, да?
          И так:
          * есть вариантные записи, но их можно наебать
          * есть ренджи, но их можно наебать
          * есть const, но и их можно наебать.

          Знаете, я так могу и в Python и в Perl семантику описать
          Ответить
          • * Вариантные записи — за пределами Standard Pascal (который я не проверял) не проверяются. Из-за отсутствия проверки их повсеместно используют не по назначению, как сишный union, а именно для эмуляции reinterpret_cast. Добавлять проверку уже поздно, потому что куча софта сломается.

            * Чтобы наебать ренджи, нужно компилировать с директивой $R-.

            * const:
            1. В параметре функции — да, легко наёбывается взятием указателя. Напрямую модифицировать компилятор всё-таки не даёт (уже на этапе компиляции запрещает присвоение).
            2. Как типизированная константа — пофиксили во Фрипаскале, если при компиляции отключить совместимость с Турбопаскалем.
            Ответить
          • К слову, в Delphi изобрели тип Variant:
            https://freepascal.org/docs-html/current/ref/refsu18.html

            Для него рантайм проверяет, значение какого типа в данный момент хранится. К сожалению, он может хранить значения только из фиксированного набора типов (скалярные, включая плавающих питухов и перечисления, строки, указатели).
            Ответить
            • В VB была такая же хуйня. Вирт наверное срал кирпичами, ведь для него формальное определение типа это чуть ли не самое важное, ради чего собссно был и изобретен язык.
              Как сейчас помню
              * запись
              * множество
              * массив
              * скаляр
              Ответить
              • Как я понял, Variant создавали ради возможности работы с OLE-OLE-OLE-OLE, точнее, с COM. Лень искать борландовскую документацию, но во Фрипаскале можно так:
                https://freepascal.org/docs-html/current/ref/refsu20.html

                Var  
                  W : Variant;  
                  V : String;  
                 
                begin  
                  W:=CreateOleObject('Word.Application');  
                  V:=W.Application.Version;  
                  Writeln('Installed version of MS Word is : ',V);  
                end;


                А вот это уже не по-паскалевски, ибо статический анализатор для строчки V:=W.Application.Version; не работает. Это синтаксический сахар: она трансформируется в вызов API, которому передаётся строка 'Application.Version'.
                Ответить
                • это Ole Automation (ком интерфейс IDispatchable или как-то так): в нем нет статически объявленных методов и пропертей, бо делался он для скриптушни
                  Ответить
          • > * есть вариантные записи, но их можно наебать

            Оказывается, «Irie Pascal» строго проверяет вариантные записи. Остальные реализации — да, можно наебать.
            Ответить
        • ты извини, но массивы передаются по значению (копированием), если не казать var.
          Так что рустеров своих ты тупо скопировал.
          Проверь
          procedure Foo(bar: array of integer);
          begin
          bar[0] := 20;
          end;
          
          type
          petuhi = array [0..20] of integer;
          
          var
          p: petuhi;
          begin;
          p[0] := 1;
          Foo(p);
          writeln(p[0]); {1}
          
          
          end.
          Ответить
          • Я бы их скопировал, если бы там было так:
            procedure asshole(roosters: array of Rooster);


            А у меня слово «const». Оно отменяет копирование (как «var»), но при этом компилятор включает статический анализатор кода, запрещающий изменение значения.
            Ответить
            • типа он понимает, шо раз там const, то можно не копирвать?
              А это в стандарте, или ты asm подсмотрел?
              Ответить
              • Это в документации. Если не ошибаюсь, расширение языка, придуманное Борландом, в Standard Pascal такого не было.
                Ответить
                • рискну предположить, что const у Вирта в 1970-м году и вовсе не было:) Это сишные веянья.

                  Икарус, как ты помнишь паскль? Ты на нем пишешь, или помнишь его с института?

                  зы; имеется ввиду const в сигнатуре функции.
                  Область модуля конечно была
                  Ответить
                  • Точно были нетипизированные константы, потому что препроцессора с дефайнами у Паскаля не было. В ИСО 7185 нетипизированные константы есть:
                    http://www.pascal-central.com/docs/iso7185.pdf
                    Да, секция, открывающаяся словом const.

                    Типизированных констант в этом документе не нашёл, как и параметров-констант у функций.
                    Ответить
                    • секция const это и были нетипизированные, по сути это был define. Тип указыватьь там было не надо, я это точно помню.

                      const может и не было, но в tp 70 было ключ слово const.
                      Ответить
                      • В TP в секции const ещё можно было указывать типизированные: у них сразу за идентификатором перед равенством указывался тип (отделялся от идентификатора двоеточием). Обычно типизированные использовались для нескалярных типов.

                        Так вот реализация в TP имела даже не дыру, а парадные ворота: типизированные константы не были защищены от изменения. По факту это были переменные с начальным значением (они помещались в инициализированную часть секции, физически присутствующую в экзешнике, в отличие от переменных из секции var, которые были в той части, которая физически в экзешнике не присутствовала и создавалась во время загрузки).

                        Во Фрипаскале это пофиксили: там сделали возможность у var указывать начальное значение, а типизированные константы защитили от изменения. Но при этом добавили переключатель, включающий режим обратной совместимости.
                        Ответить
                        • ахахаха, всё так
                          https://i.postimg.cc/85WrpMf8/lal.png
                          Ответить
                        • зы: напомнило байку из моего детства

                          Студент: если я покажу вам багу паскаля -- дадите мне зачет?
                          Препод: не может быть такого, паскаль -- безглючный язык
                          Студент
                          var
                          implementation: integer
                          Ответить
                          • А как это работало и в каком компиляторе?

                            В TP, начиная с 4.0, не скомпилируется, потому что слово IMPLEMENTATION зарезервировали для модулей.
                            Ответить
                          • Честно проверил BP 7.0, TP 6.0, TP 5.5, TP 4.0 и даже Microsoft Quick Pascal 1.0 (это первая и последняя версия «Паскаля» в реализации «Микрософта», по сути пародия на TP 4.0). Во всех компилятор сообщает, что implementation — зарезервированное слово. Это не противоречит хелпу.

                            Это слово — расширение языка, придуманное «Борландом» в версии 4.0, когда добавили модульную систему.

                            Что не так?
                            Ответить
                            • Можно я попробую:

                              Мне тут говорили, что в стандартном паскале модульцев не было, поэтому прога использующая идентификатор interface работала в стандартном и обсирается в турбированном и его последователях?

                              Я угандал?
                              Ответить
                              • То есть нарушили обратную совместимось.
                                Ответить
                                • Именно так. В TP 3.0 и в более старых такой код компилировался, поскольку слова interface и implementation не были зарезервированы.

                                  По той же самой причине сишный код, содержащий переменные с именем «class», нельзя скомпилировать в «C++».
                                  Ответить
          • 1. Как у тебя: выводит 1.

            2. Добавим var — вернёт 20.
            procedure Foo(var bar: array of integer);


            3. Добавим const:
            procedure Foo(const bar: array of integer);

            Не компилируется:
            c2.pas(3,1) Error: Can't assign values to const variable
            Ответить
            • 1. just to make sure: у тебя fpc или tp в dosbox?

              2. Если я напишу
              type
              PPetuh = ^Integer;
              
              procedure foo(const t: PPetuh);

              это будет константный указатель на питуха, или указатель на константного питуха?
              Пушо у меня он отлично меняетсчя
              t^ := 12;


              зы: бля, как давно я не брал в руки шашку
              пишу turbo.exe в dosbox, и мне снова 15 лет
              Ответить
              • Сейчас fpc, но могу и в tp проверить.

                Это константный указатель на питуха. Запрещено менять указатель, но не питуха.
                Ответить
                • как выразить указатель на константново питуза?
                  Ответить
                  • Честно? Не знаю. Боюсь, что в Паскале все указатели разрешают изменение разыменованных данных.
                    Ответить
                    • фу говно

                      хорошо, что 20 лет назад нам было на это похуй
                      Ответить
                      • Сишка и Паскаль развивались в разных направлениях.

                        В Си массив — это сахар над указателем. В Си модно было писать while(*p++ = *q++) и вообще использовать арифметику указателей, где только можно. Поэтому и задумались о защите объектов, на которые ссылаются указатели.

                        В Паскале же арифметики указателей нет. Можно, конечно, кастовать указатель в число, изменить и кастовать обратно в указатель. Можно использовать инкремент/декремент. Но так обычно не делают. В Паскале модно объявлять типы и делать всё через типы: массивы, записи и т. п. Заодно получим проверку границ индекса массива (которую в Си нужно делать вручную).

                        Возможно, по этой причине разработчики Паскаля (Вирт и разработчики более поздних реализаций) сразу об указателях на константного питуха не задумались.
                        Ответить
                        • >В Си массив — это сахар над указателем.
                          struct petushok {
                           char jaichko[42];
                          };
                          struct kurochka {
                           char *jaichko;
                          }


                          точно сахар?
                          Ответить
                          • И правда, внутри структуры — это разные сущности. Внутри структуры бывают настоящие массивы.
                            Ответить
                            • И на стеке бывает.
                              Сравни

                              char jaichko[42]; //выделит 42 чара на стеке
                              char jaichko*; //выделит указатель там же

                              А в сигнатуре функции не бывает. И в возвращаемом значении тоже.
                              Причем в сигнатуре можно написать, и ничего за это не будет

                              void foo(char petuh[]) {
                              }

                              короче, неконсистентное говно эта ваша сисшка
                              Ответить
                              • Зато как развивает мозг! Сколько всего помнить нужно!
                                Ответить
      • Кого ебет паскаль?
        Ответить
        • Меня ебет. Паскаль это мое детство, моя первая змейка, и зеленая книжка "алгоритмы и структуры данных".
          https://cdn1.ozone.ru/multimedia/c650/1004496212.jpg

          Я помню, как охуел там от такого приема: ты ищешь что-то в массиве, и на каждом шаге проверяешь, что массив еще не кончился, и что в нем нет того, что ты ищещь.

          Но ты можешь вставить искомый элемент в последний элемент массива, и элиминировать проверку на конец массива: ты всегда что-то найдешь, просто если ты нашел в самом конце, то по сути не нашел.

          В те года это было реально круто
          Ответить
          • Хорошая книжка, раз такому учит )))
            Ответить
            • Там вообще было много забавных алгоритмов: например, кольцевой буфер.
              Если у тебя есть 10 байт памяти, то сделать в них стек очень легко, а как сделать в них очередь?
              Вот у тебя заполнились 10 байт, и ты забрал из очереди 1 элемент. Очередь имеет свободное место с головы, но в хвост ее ничего не вставишь.

              Казалось бы: можно подвинуть все на 1 байт, но нахуй двигать, если можно сделать кольцевой буфер, и указатель на место "вставки"? В итоге ты вставляешь в голову массива, но это как-бы "хвост"
              Ответить
              • В рот мне ноги! В голову мне хвост!
                Ответить
                • я ее нашел!
                  http://tka4.org/materials/lib/Articles-Books/Numerical%20Algorithms/%D0%92%D0%B8%D1%80%D1%82%20%D0%9D.%20%D0%90%D0%9B%D0%93%D0%9E%D0%A0%D0%98%D0%A2%D0%9C%D0%AB%20%D0%98%20%D0%A1%D0%A2%D0%A0%D0%A3%D0%9A%D0%A2%D0%A3%D0%A0%D0%AB%20%D0%94%D0%90%D0%9D%D0%9D%D0%AB%D0%A5.%20%D0%9C.%D0%9C%D0%B8%D1%80%201989.pdf

                  страница 59
                  Ответить
                  • Сейчас придёт Сёма, и научит тебя копипастить ссылки правильно.
                    Ответить
                    • Сёма скажет что паскаль, кольцевой буфер, поиск в массиве, и вообще алгоритмы и структуры данных не нужны.
                      Ответить
                      • Это всё наверняка либо математика, либо прыщеговно.
                        Ответить
                        • либо стоит 71 евро.

                          зы: смори, какой крутой блог
                          https://socket3.wordpress.com/

                          напрмиер вот
                          https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/
                          Ответить
    • А в C# некоторые новые служебные слова (например, относящиеся к Linq) работают только в контексте, а так могут быть использованы как имена переменных и т.п.:
      int[] from = { -1, 0, 1 };
      int select = (from v in @from where v > 0 select 2*v).First();
      Console.WriteLine(select); // 2

      (@ перед from нужна как раз чтобы показать, что это идентификатор, т.к. в данном контексте это уже зарезервированное слово)
      Ответить
      • Хорошо, что они оставили возможность явно использовать идентификатор в новом контексте (@).

        Говорят, в «PL/1» значков для отделения идентификаторов от ключевых слов не было. Такой код был валиден:
        IF IF = THEN THEN THEN = ELSE;
                     ELSE ELSE = IF;
        Ответить
      • Перевёл на «PHP»:
        <?php
        
        ${'function'} = [ -1, 0, 1 ];
        ${'reset'} = @reset(array_map(function($v){return 2*$v;}, array_filter(${'function'}, function($v){return $v>0;})));
        
        echo ${'reset'}, PHP_EOL;

        Собачка тут только для того, чтобы передать rvalue в функцию reset.
        Ответить

    Добавить комментарий