WeChat не единственный. Есть Ali и куча мелких брендов. Да, в Китае есть ряд ограничений, которых никому нельзя нарушать. Но отсутствие конкуренции в "свободе высказывания на ряд тем" не равно отсутствие конкуренции в борьбе за магазинчик, который выбирает, где ему разместить своё мини приложение.
Затем, что C даёт выбор: я могу инициализировать структуру и тогда автоматически все байты выравнивания занулятся (а также все поля, которые не были указаны при инициализации), могу не инициализировать структуру и тогда ничего зануляться не будет. В D, как я понял, если не делаешь инициализацию сам, то структура сама инициализируется нулями. В итоге будет ряд случаев, когда компилятор не сделает оптимизацию и в рантайме будет выполнен ряд лишних операций. Можно попросить компилятор кидать варнинги (а их отображать как ошибки), когда какая-то переменная не инициализирована, а в местах где инициализация не требуется ставить атрибут аля "так и задумано". С массивами тоже всё тривиально: делаем функции, которые работают с "проверенными данными" (То есть, если программист не накосячил, то выхода за пределы массива не будет) и функции, работающие с внешними данными (проверки в рантайме потребуются). Для минимизации ошибки программиста ставим ассерты и запускаем дебаг версию с санитайзерами.
Эм, в C тоже можно сравнивать структуру по элементам. Если нужен синтаксический сахар, то можно использовать CPP, перегрузить оператор сравнения, который будет сравнивать так, как нужно вам.
Если хотите использовать memcmp для сравнения, то C никак вам не запрещает в структурах инициализировать одним значением байты выравнивание (зачастую нулями). Да, на C это будет некрасиво, но если нужен синтаксический сахар, то есть CPP.
Вообще, плох тот язык системного программирования, который по умолчанию делает кучу ненужных вещей. Вещи, вроде, проверки границ массива, инициализации байтов выравнивания должны делаться исключительно там, где в этом есть необходимость.
Не очень понятно преимущество в виде проверок границ массивов и инициализации переменных. На C тоже можно проверять границы массивов и инициализировать абсолютно все переменные. Да, C не позволяет красиво применять оператор [] для доступа к элементу с проверкой. Но тот же CPP с его "перегрузкой" операторов вполне разрешает делать проверку с использованием оператора [], инициализировать все переменные, а также использовать умные указатели для борьбы с утечками памяти.
Согласно стандарту C — char "интегральный" (целочисленный) тип. Fixed width integer types — просто ссылки на "фундаментальные" типы. Фундаментальных целочисленных типов всего 5: char, short, int, long, long long. Если, ни short, ни int, ни long, ни long long не 4 байта, то не будет fixed width integer type на 4 байта.
Допустим, у нас есть платформа, для которой оптимальным целочисленным типом является 8 байт. Эта платформа также поддерживает типы: 1, 2, 4 байта. В этом случае char будет 1 байт. Попробуем сделать int 8 байт. Тогда у нас остаётся один тип в Си (short) и два типа платформы (2 и 4 байта).
Речь немного про другое шла. Если у нас есть гипотетическая архитектура, для которой оптимальным типом является 8 байт, при этом эта архитектура поддерживает 2 и 4 байта, то int никак не может быть 8 байт. Значит int не всегда может быть самым оптимальным типом.
Ну так я и не отрицал, что бывают архитектуры, где в байте больше 8 бит. Только если на этой архитектуре есть типы 1, 2, 4 байта, то int не может быть БОЛЬШЕ 4 байт, ибо тогда не будет типа, который описывает либо 2, либо 4 байта. До int у нас есть всего 2 типа: char и short. Char всегда равен одному байту. Если, условно, мы делаем int 8 байтам, то у нас остаётся только short, а нам нужно описать два типа: 2 байта и 4 байта.
Увы, int не всегда самый оптимальный. Int не будет больше 4 байт. Так что если для процессора самый оптимальный тип 8 байт, то int не сможет быть оптимальным типом.
Потому что до int есть только два типа: char и short. Char всегда 1 байт, если мы сделаем int 8 байтами, то не будет типа, который означает либо 4, либо 2 байта.
Ну это хак, а не фича языка. Да и хотелось бы, чтобы в C++ была возможность типам диапазоны значений указывать.
Вот есть у нас Utf-8 нуль-термированная строка. Первый тип — октет. Октет принимает такие-то значения. Второй тип — «символ». Это динамическая структура от 1 до 4 октет. Первый октет вот такой-то и по нему можно узнать длинну этой структуры, второй октет может принимать вот такие-то значение и т.д. Третий тип — сама строка. Есть один символ, означающий конец строки, он встречается всего один раз и всегда в конце. При чём он состоит из одного октета, который полностью заполнен нулями. Если я неправильные значения запишу в данные типы, то согласен на UB.
Ну так mov нам в любом случае писать надо. То, что процессор, вместо физического переписывания данных в регистрах, меняет регистровый файл — его дело. Количество инструкций от этого не меняется.
Ну так x86-64 имеют RISC ядро. То что много инструкций поддерживаются процессором, не значит, что каждая инструкция распаяна, много делается программно. Просто сейчас процессоры скорее некий сервер, которому мы говорим некие абстрактные комманды, а он уже делает что хочет. Вон, в Intel ME встроили. По сути другой процессор, который ещё ОС Minix исполняет. Сейчас процессоры — системы на чипе.
Ну компиляторы предоставляют всякие атрибуты и built in для подсказок. Ну, а, вообще, это скорее проблема языка, так как часто мы знаем какие значения может принимать байт или группа байт, но ни C, ни C++ возможностей указать это не предоставляют.
Наверное, правильным ответом будет, что не считаются. Интересно, скорее, сколько инструкций процессора использует компилятор при компиляции чистого C. Если компилятору напрямую сказать используй эту инструкцию, то очевидно, что он использует её.
Правда, это очень сложная задача. И либо нужно разбирать исходники компилятора, чтобы понять какие инструкции он будет вставлять, либо под каждую инструкцию писать такой C код, при котором данную инструкцию стоило бы использовать.
Эм, а при чём тут ассемблер. В статье ни строчки ассемблера, ни слова про таймер процессора и т.д. То что есть ссылка на текст программы на ассемблере не достаточно, чтобы публиковать статью с меткой ассемблер (хоть бы метку basic добавили бы)
WeChat не единственный. Есть Ali и куча мелких брендов. Да, в Китае есть ряд ограничений, которых никому нельзя нарушать. Но отсутствие конкуренции в "свободе высказывания на ряд тем" не равно отсутствие конкуренции в борьбе за магазинчик, который выбирает, где ему разместить своё мини приложение.
Затем, что C даёт выбор: я могу инициализировать структуру и тогда автоматически все байты выравнивания занулятся (а также все поля, которые не были указаны при инициализации), могу не инициализировать структуру и тогда ничего зануляться не будет. В D, как я понял, если не делаешь инициализацию сам, то структура сама инициализируется нулями. В итоге будет ряд случаев, когда компилятор не сделает оптимизацию и в рантайме будет выполнен ряд лишних операций. Можно попросить компилятор кидать варнинги (а их отображать как ошибки), когда какая-то переменная не инициализирована, а в местах где инициализация не требуется ставить атрибут аля "так и задумано". С массивами тоже всё тривиально: делаем функции, которые работают с "проверенными данными" (То есть, если программист не накосячил, то выхода за пределы массива не будет) и функции, работающие с внешними данными (проверки в рантайме потребуются). Для минимизации ошибки программиста ставим ассерты и запускаем дебаг версию с санитайзерами.
Эм, в C тоже можно сравнивать структуру по элементам. Если нужен синтаксический сахар, то можно использовать CPP, перегрузить оператор сравнения, который будет сравнивать так, как нужно вам.
Если хотите использовать memcmp для сравнения, то C никак вам не запрещает в структурах инициализировать одним значением байты выравнивание (зачастую нулями). Да, на C это будет некрасиво, но если нужен синтаксический сахар, то есть CPP.
Вообще, плох тот язык системного программирования, который по умолчанию делает кучу ненужных вещей. Вещи, вроде, проверки границ массива, инициализации байтов выравнивания должны делаться исключительно там, где в этом есть необходимость.
Не очень понятно преимущество в виде проверок границ массивов и инициализации переменных. На C тоже можно проверять границы массивов и инициализировать абсолютно все переменные. Да, C не позволяет красиво применять оператор [] для доступа к элементу с проверкой. Но тот же CPP с его "перегрузкой" операторов вполне разрешает делать проверку с использованием оператора [], инициализировать все переменные, а также использовать умные указатели для борьбы с утечками памяти.
Согласно стандарту C — char "интегральный" (целочисленный) тип. Fixed width integer types — просто ссылки на "фундаментальные" типы. Фундаментальных целочисленных типов всего 5: char, short, int, long, long long. Если, ни short, ни int, ни long, ни long long не 4 байта, то не будет fixed width integer type на 4 байта.
Допустим, у нас есть платформа, для которой оптимальным целочисленным типом является 8 байт. Эта платформа также поддерживает типы: 1, 2, 4 байта. В этом случае char будет 1 байт. Попробуем сделать int 8 байт. Тогда у нас остаётся один тип в Си (short) и два типа платформы (2 и 4 байта).
Речь немного про другое шла. Если у нас есть гипотетическая архитектура, для которой оптимальным типом является 8 байт, при этом эта архитектура поддерживает 2 и 4 байта, то int никак не может быть 8 байт. Значит int не всегда может быть самым оптимальным типом.
Ну так я и не отрицал, что бывают архитектуры, где в байте больше 8 бит. Только если на этой архитектуре есть типы 1, 2, 4 байта, то int не может быть БОЛЬШЕ 4 байт, ибо тогда не будет типа, который описывает либо 2, либо 4 байта. До int у нас есть всего 2 типа: char и short. Char всегда равен одному байту. Если, условно, мы делаем int 8 байтам, то у нас остаётся только short, а нам нужно описать два типа: 2 байта и 4 байта.
По стандарту C char имеет такое же количество бит, что и байт.
А можете привести архитектуру, для которого sizeof(int) больше четырёх?
Кста, gcc для int_fast32_t и int_fast16_t использует 8 байт на amd64.
Вопрос был почему int не может быть 8 байт. А при чём тут биты, вообще, не понятно. Sizeof в байтах измеряет, а не в битах, же.
Увы, int не всегда самый оптимальный. Int не будет больше 4 байт. Так что если для процессора самый оптимальный тип 8 байт, то int не сможет быть оптимальным типом.
Потому что до int есть только два типа: char и short. Char всегда 1 байт, если мы сделаем int 8 байтами, то не будет типа, который означает либо 4, либо 2 байта.
Вот есть у нас Utf-8 нуль-термированная строка. Первый тип — октет. Октет принимает такие-то значения. Второй тип — «символ». Это динамическая структура от 1 до 4 октет. Первый октет вот такой-то и по нему можно узнать длинну этой структуры, второй октет может принимать вот такие-то значение и т.д. Третий тип — сама строка. Есть один символ, означающий конец строки, он встречается всего один раз и всегда в конце. При чём он состоит из одного октета, который полностью заполнен нулями. Если я неправильные значения запишу в данные типы, то согласен на UB.
Правда, это очень сложная задача. И либо нужно разбирать исходники компилятора, чтобы понять какие инструкции он будет вставлять, либо под каждую инструкцию писать такой C код, при котором данную инструкцию стоило бы использовать.
Эм, а при чём тут ассемблер. В статье ни строчки ассемблера, ни слова про таймер процессора и т.д. То что есть ссылка на текст программы на ассемблере не достаточно, чтобы публиковать статью с меткой ассемблер (хоть бы метку basic добавили бы)