LINUX.ORG.RU

Комитет не может остановиться..

 , ,


1

4

Привет, ЛОР!

Я просто оставлю это здесь: https://isocpp.org/files/papers/P2996R4.html

Для Ъ: в C++26 будет добавлена поддержка статической рефлексии. Теперь C++ будет компилироваться ЕЩЁ ДОЛЬШЕ.

★★★★★
Ответ на: комментарий от zx_gamer

Только если используешь расширенный C, например GNU. attribute((packed))

Никакого обычного C не существует, есть только C с расширениями. Без них у тебя тупо лялех не соберется.

cumvillain
()
Ответ на: комментарий от DumLemming

Я там ссылочку давал, потому что челик уже писал мне, но потом хорошо подумал и удалил своё сообщение. Но ссылочку я на пост почему я так считаю оставлю тут. Комитет не может остановиться.. (комментарий) Если надо могу дать пруф даже на все цифры в этом посту, они не от балды написаны если что, а вполне известные в узких кругах тех времён разработчиков на C# люди бочку на рефлексию катили. Блин опечатку увидел, не в 2000 а в 2008 году.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от zx_gamer

Твой код – полное говно. Не пиши так нигде, а то тебя отмудохают арматуриной и пальцы переломают.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

Если совсем упороться, можно затолкать оба представления в union. Проблема в том, что «проще» нет – конвертировать из be в le все равно надо, только теперь у тебя ещё вторая структура и union.

cumvillain
()
Ответ на: комментарий от zx_gamer

Мой код правильно работает с любой архитектурой ЭВМ и компилятором языка Си. А ваш нет.

Нет, это мой код работает на любой архитектуре ЭВМ. Твоего кода не существует, потому что ты его не смог написать – все что у нас есть, это две декларации структур.

cumvillain
()
Ответ на: комментарий от zx_gamer

чёт реально странно выглядит, вот это вот зачем так расписывать?:

struct some_data_bin {
        char some_field[4];
        char another_field[2];
};

всё равно же memcpy-ить придётся, почему просто буфер не взять?

zurg
()
Ответ на: комментарий от zx_gamer

Нет никакой травмы. Я категорически отказываюсь признавать бредни сумасшедших ISOшников за стандарт Си. Пусть сами этим говном пользуются.

А бредни сумасшедших ANSIшников из комитета X3J11 лучше?

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Нет никакой травмы. Я категорически отказываюсь признавать бредни сумасшедших ISOшников за стандарт Си. Пусть сами этим говном пользуются.

А бредни сумасшедших ANSIшников из комитета X3J11 лучше?

Будем честны: сами Керниган и Ритчи, судя по результатам их трудов, особым душевным здоровьем не отличались.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от static_lab

Лучше. Единственное, что у них получилось неудачного: объявление переменных (тип не слева на право, а как «туда-сюда» читается) и совсем уж примитивный макропроцессор.

zx_gamer ★★★
()
Ответ на: комментарий от static_lab

Обмазывать каждый класс кучей макросов — такое себе. А потом оно ещё и в C++98 работает не очень корректно.

Этот Boost.Move появился уже после выхода С++11 по мотивам оттуда, а до этого никакой распространенной move семантики не было, разве что только вручную через swap. И «аналогом» std::unique_ptr в том же бусте был boost::scoped_ptr который перемещаться не умел, тупо держал указатель.

anonymous
()
Ответ на: комментарий от zx_gamer

Лучше. Единственное, что у них получилось неудачного: объявление переменных (тип не слева на право, а как «туда-сюда» читается) и совсем уж примитивный макропроцессор.

И вагон Undefined Behaviour.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от zx_gamer

/0, *NULL, i = i++, что я еще забыл?

лол примерно всё ты забыл, балда.

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

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от rupert

Ну вот покажи мне, где здесь enable_if не может быть заменён концептами?

SFINAE это не обязательно enable_if. Это сам принцип, что если у тебя возникла ошибка компиляции, то не возвращаем ошибку, а ищем дальше, вдруг что соберётся.

В частности тут:

///////////////////// Helper for SFINAE on fields count
template <class T, std::size_t... I, class /*Enable*/ = typename std::enable_if<std::is_copy_constructible<T>::value>::type>
constexpr auto enable_if_constructible_helper(std::index_sequence<I...>) noexcept
    -> typename std::add_pointer<decltype(T{ ubiq_lref_constructor{I}... })>::type;

template <class T, std::size_t... I, class /*Enable*/ = typename std::enable_if<!std::is_copy_constructible<T>::value>::type>
constexpr auto enable_if_constructible_helper(std::index_sequence<I...>) noexcept
    -> typename std::add_pointer<decltype(T{ ubiq_rref_constructor{I}... })>::type;

template <class T, std::size_t N, class /*Enable*/ = decltype( enable_if_constructible_helper<T>(detail::make_index_sequence<N>()) ) >
using enable_if_constructible_helper_t = std::size_t;

Можно заменить std::enable_if на концепты, но sfinae от этого никуда не денется. Оно в самом методе определения кол-ва полей тут заложено, когда ты пытаешься втиснуть какое-то кол-во инициализаторов структуре, и если возникает ошибка, то впихиваешь меньше. Это вся суть этой либы и это буквально sfinae.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от zx_gamer

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

zurg
()
Ответ на: комментарий от zx_gamer

Ну эти ограничения вполне очевидны. И сводятся к тому, что не надо лезть в память, в которую лезть нельзя.

Кому очевидны? Тут половина сишников членом в грудь себя бьют и орут, что указатель – это просто число.

@zurg правильно написал: это всё должно быть либо ошибкой сборки, либо это не должно вообще быть отдельной фишкой. Весь концепт Undefined Behaviour в сишке – сплошной спидорак жопы.

P.S. @zurg, в последнем стандарте этот список растянут на 14 страниц A4 лол

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 2)
Ответ на: комментарий от rupert

Перегрузка enable_if_constructible_helper по copy_constructible концепту не требует sfinae.

Перегрузка по is_copy_constructible не требует. Перегрузка enable_if_constructible_helper_t по std::size_t N требует, т.к. перегрузка enable_if_constructible_helper по index sequence работает именно через sfinae.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от zurg

Потому что выявление ошибок с указателями неразрешимая задача. Как вы будете это проверять в компиляции, если, например, вы пишете интерпретатор машинного кода? Вы не знаете в compile-time какую сущность будут представлять эти указатели.

zx_gamer ★★★
()
Ответ на: комментарий от hateyoufeel

Ну вот смотри. Ты считываешь 2 числа, делишь одно на другое и выводишь в stdout результат. Если ты не проверил что делитель не 0, то что должен делать компилятор? Он логично предполагает, что никто никогда на 0 делить не будет. И код будет вести себя некорректно, если деление на 0 все-таки случится. Или вы предлагаете всегда заставлять программиста проверять, что делитель не 0? Но это глупо, потому что в каких-то ситуациях ноль не может получиться НИКОГДА.

zx_gamer ★★★
()
Ответ на: комментарий от zx_gamer

Ну вот смотри. Ты считываешь 2 числа, делишь одно на другое и выводишь в stdout результат. Если ты не проверил что делитель не 0, то что должен делать компилятор?

Компилятор должен скомпилировать код, который делит на ноль. Всё остальное – не его собачье дело.

Или вы предлагаете всегда заставлять программиста проверять, что делитель не 0? Но это глупо, потому что в каких-то ситуациях ноль не может получиться НИКОГДА.

Зато не глупо выдавать полное говно вместо кода наружу, да.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Компилятор должен скомпилировать код, который делит на ноль.

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

Зато не глупо выдавать полное говно вместо кода наружу, да.

Собери программу с санитайзером (для gcc и clang -fsanitize=undefined,address). В бинарник будет вшита библиотека, которая остановить программу в случае UB и напишет где и когда оно произошло. Но не удивляйся, что бинарник будет тяжелым и медленным. Это только для дебажной сборки, релизную сборку следует собирать без санитайзера.

P.S. санитайзеры бывают разные для отлавливания разных ошибок.

zx_gamer ★★★
()
Ответ на: комментарий от zx_gamer

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

Не так то, что ты не понимаешь, что такое undefined behaviour в C. Undefined behaviour относится к поведению компилятора. В данном случае, если в коде есть деление на 0 без проверки, то компилятор может выдать любое говно. Например:

int a, b;
scanf("%d %d\n", &a, &b);
int c = a / b;

if(b == 0) {
  puts("OOOOPS!");
}

В данном случае, блок if будет выкинут, потому что компилятор считает, что b не может быть 0.

Собери программу с санитайзером (для gcc и clang -fsanitize=undefined,address). В бинарник будет вшита библиотека, которая остановить программу в случае UB и напишет где и когда оно произошло.

Повторюсь, ты не понимаешь, что такое undefined behaviour в C. Впрочем, мы уже выяснили выше, что ты и программировать-то не умеешь.

UBSan работает далеко не всегда. Это раз. Два, для его срабатывания нужно воспроизвести все условия в коде, что может быть сложнее чем кажется. А всё потому что каким-то кретинам почти 50 лет назад сложно было язычок спроектировать.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от Ivan_qrt

Не надо разводить мифологию. SFINAE это не принцип, а совершенно конкретная фича компиляции. К концептам это не имеет никакого отношения. Концепты вообще могут применяться к нешаблонным функциям-членам, есличо. И то что в каких-то контекстах концепты дают тот же результат как и SFINAE, не далает их одинаковыми, это в принципе разные языковые конструкции.

peacelove
()
Ответ на: комментарий от hateyoufeel

Я понимаю. Компилятор может делать в случае UB что угодно. Это нужно оптимизатору. Компилятор считает, что UB никогда не происходит. А если происходит — то программист сам дурак.

В данном случае, блок if будет выкинут, потому что компилятор считает, что b не может быть 0.

Логично. Компилятор же считает, что на 0 никто нигода делить не будет. Но если деление будет под if, то не будет выкинуто.

zx_gamer ★★★
()
Ответ на: комментарий от hateyoufeel

это всё должно быть либо ошибкой сборки, либо это не должно вообще быть отдельной фишкой. Весь концепт Undefined Behaviour в сишке – сплошной

они наверное хотели по аналогии со SFINAE сделать UBINAE.

Unspecified Behaviour is not an error.

это декларативное в императивном.

anonymous
()
Ответ на: комментарий от zx_gamer

Единственное, что у них получилось неудачного: объявление переменных (тип не слева на право, а как «туда-сюда» читается) и совсем уж примитивный макропроцессор.

вот возьми например BCPL где foo!n <=> C foo[n] и то как там сделаны указатели (хотя есть и infix byte indirection foo%n

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

попытки построить транзитивное замыкание относительно типов приведут к

The interpretation of any value was determined by the operators used to process the values. (For example, + added two values together, treating them as integers; ! indirected through a value, effectively treating it as a pointer.) In order for this to work, the implementation provided no type checking.

The mismatch between BCPL’s word orientation and byte-oriented hardware was addressed in several ways. One was by providing standard library routines for packing and unpacking words into byte strings. Later, two language features were added: the bit-field selection operator and the infix byte indirection operator (denoted by %).

то есть уже в двух байтах – остроконечники и тупоконечники с LE, BE заблудились.

как должны быть нормально реализованы указатели: если foo'address в аде это примерно &foo в си – то foo'access который через рефлексию к стандартным пакетам и типам и общий механизм атрибутов (расширяемый) позволяет контролировать корректно типизированные указатели во время компиляции.

во время выполнения – происходит стирание типов и отсуствие различия между foo!n и foo%n

нормально типизированные ссылки – корректность их типизации должен гарантировать компилятор во время компиляции.

если ссылка на Х это объект второго класса, то разыменование ссылки и прочий housekeeping (невозможность например создать новый символ как GENSYM в лиспе) – определяют невозможность создавать объекты первого класса.

например, сделать лямбду на plain C – потребуется понимать как делать этот housekeeping в отсутствие GENSYM, интерфейса между препроцессором/компилятором и CTFE средой компиляции/интерпретатором и средой выполнения.

например, в обероне из-за этого для поддержки модулей добавили сборщик мусора. чтобы можно было не возится с тем caller/callee выделяет/освобождает, а реализовать модуль как first class object.

и совсем уж примитивный макропроцессор.

он хоть и примитивный, но его достаточно например чтобы написать ассемблер.

ассемблер просто пишется на awk или на препроцессоре Си (см. реализацию 8a в inferno os – там по сути большинство ассемблера написано макросами сишными. хотя есть и какой-то сахар через lex/yacc).

препроцессор работает на уровне лексем, токенов. но при этом у него нет аналога D-шного трейта is_compiling проверяющего что результат его подстановки – корректный имеющийся токен.

в итоге макросы далеко не так полезны как макросы того же лиспа, например. той же схемы где гигиена и модульные макросы или какого-то рефлексивного лиспа типа SINK kernel vau-exprs или 3-lisp.

даже в PL/I был более полезный препроцессор – он позволял конструировать строку как угодно (аналогично string mixin в D).

при этом правда, всё равно области видимости на уровне строк.

то есть, реализовать ту же лямбду было бы проблематично.

в С++>=11 кстати лямбды реализовали как функторы, перегрузкой операции (). теперь чтобы понять передаётся по значению или по ссылке нужно обмазаться кучей сахара (что как-то нивелирует весь смысл лямбды как composable, составимой компактной простой в использовании first class object конструкции).

anonymous
()