Ну ничего, завезут скоро std::start_lifetime_as и заживём!
P.S.
В нормальных языках спорят о каких-то реальных проблемах, какие-то там подходы к решению тех или иных задач, но самые жаркие споры в С++ комьюнити до сих пор о самом С++. Гспди, на что я трачу жизнь...
Так стоп. После того, как я скастил 0x3 к указателю, с точки зрения синтаксиса программы последующее разыменование - это обращение к объекту.
У компилятора нет никакой возможности доказать, что там этого объекта нет. Этот объект может жить в другом TU. Следовательно компилятор ничего не остаётся, кроме как поверить мне на слово.
Я не согласен. Конечно синтаксически С++ достаточно прост (хотя и Haskell не сказал бы я, что сложен). Основная убер фича С++ - это UB. Писать код без него - подобно искусству каллиграфии. Haskell может быть сложен с той точки зрения, что требует некоторого математического бекграунда для понимания. Но с точки зрения способов выстрелить в себе в ногу С++ впереди всей планеты.
Что значит речь не о том? Я компилятору вполне внятно сказал "по этому адресу лежит объект с типом volatile int, я хочу в него записать значение, и меня вообще не волнует, что ты об этом думаешь". И компилятор обязан сгенерировать код. Без вариантов. Компилятор компилирует один TU, и может тупо не видеть этот int. Но будет он там или нет - дело даже не компилятора. Компилятор не располагает объекты в бинаре. Линковщик это делает.
В данном случае компилятор может вообще выкинуть этот код, если он докажет, что там лежит не инт.
Мне лень ходить в стандарт, поэтому я схожу на cppreference.
volatile object - an object whose type is volatile-qualified... volatile accesses cannot be optimized out or reordered with another visible side effect that is sequenced-before or sequenced-after the volatile access
А я утверждаю, что UB - это прежде всего behaviour. Компилятор всегда на строчку `*((volatile int*)0x3) = 1` сгенерирует один и тот же код. Он не может не сгенерировать код записи в память, когда его об этом явно просят. С точки зрения компилятора поведение очень defined.
А вот во время исполнения мы можем получить как defined, так и undefined поведение. Если мы создали все условия, чтобы по адресу 0x3 всё было валидно, значит поведение всегда будет well-defined. В ином случае - да UB.
При таком взгляде на проблему, линкер скрипты вполне себе обеспечивают гарантированно определённое поведение.
Не какой-то, а конкретный код генерируется. UB происходит не на стадии компиляции, а на стадии исполнения программы. Если по адресу записываемому адресу на момент исполнения программы всегда живёт объект нужного типа, абсолютно валидно туда что-то писать. До момента старта программы UB нет.
Вы просто пессимист. Ввиду того, что UB включает в себя всё что угодно, включая валидную программу на С++, можно сказать, что любая программа с UB написана на С++ :)
Кроме того, есть правила, описывающие, что конкретно надо сделать, чтобы там было что-то валидное. Если вы этого не сделали, то там ничего валидного нет.
Да, но не сказано ГДЕ нужно это сделать. Я могу это сделать в любом TU в программе. Это никак не меняет того факта, что если я разместил какой-то int где угодно в программе по адресу 0x3 и этот int всё еще там, пока я пишу в адрес 0x3 - это абсолютно валидный код, ничего не нарушающий, не создающий UB, и т.д. и т.п.
В С++ нет ничего синтаксически некорректного в желании записать что-то по любому адресу. Стандарт говорит: "Если по этому адресу лежит то, что ты туда пишешь, то всё нормально". А вот если "там лежит не то, что ты туда пишешь" или "там ничего не лежит", то тут UB.
Битый пиксель и черная дыра самые завораживающие конечно
Я предлагаю не иметь на кухне телевизор) Решает проблему на 100%)
На фоне трат на одну широко нашумевшую войну, траты на Уебб, равно как и нытье правительств об отсутствии денег, звучат оч смешно.
Но ведь можно полировать параллельно?)
Ещё раз - дайте мне кусок стандартам, который подтверждает, что писать в случайную память - это UB
И тем не менее он генерируется. Чудеса, не иначе
Ну ничего, завезут скоро std::start_lifetime_as и заживём!
P.S.
В нормальных языках спорят о каких-то реальных проблемах, какие-то там подходы к решению тех или иных задач, но самые жаркие споры в С++ комьюнити до сих пор о самом С++. Гспди, на что я трачу жизнь...
Прошу прощения, но я спать. Я уже час как хочу лечь, но этот бессмысленный спор меня затянул :)
Так стоп. После того, как я скастил
0x3к указателю, с точки зрения синтаксиса программы последующее разыменование - это обращение к объекту.У компилятора нет никакой возможности доказать, что там этого объекта нет. Этот объект может жить в другом TU. Следовательно компилятор ничего не остаётся, кроме как поверить мне на слово.
Я не согласен. Конечно синтаксически С++ достаточно прост (хотя и Haskell не сказал бы я, что сложен). Основная убер фича С++ - это UB. Писать код без него - подобно искусству каллиграфии. Haskell может быть сложен с той точки зрения, что требует некоторого математического бекграунда для понимания. Но с точки зрения способов выстрелить в себе в ногу С++ впереди всей планеты.
Что значит речь не о том? Я компилятору вполне внятно сказал "по этому адресу лежит объект с типом volatile int, я хочу в него записать значение, и меня вообще не волнует, что ты об этом думаешь". И компилятор обязан сгенерировать код. Без вариантов. Компилятор компилирует один TU, и может тупо не видеть этот int. Но будет он там или нет - дело даже не компилятора. Компилятор не располагает объекты в бинаре. Линковщик это делает.
Мне лень ходить в стандарт, поэтому я схожу на cppreference.
Да. Но это ведь не означает, что внутри UB нет валидной программы на С++ :)
А я утверждаю, что UB - это прежде всего behaviour. Компилятор всегда на строчку `*((volatile int*)0x3) = 1` сгенерирует один и тот же код. Он не может не сгенерировать код записи в память, когда его об этом явно просят. С точки зрения компилятора поведение очень defined.
А вот во время исполнения мы можем получить как defined, так и undefined поведение. Если мы создали все условия, чтобы по адресу 0x3 всё было валидно, значит поведение всегда будет well-defined. В ином случае - да UB.
При таком взгляде на проблему, линкер скрипты вполне себе обеспечивают гарантированно определённое поведение.
Не какой-то, а конкретный код генерируется. UB происходит не на стадии компиляции, а на стадии исполнения программы. Если по адресу записываемому адресу на момент исполнения программы всегда живёт объект нужного типа, абсолютно валидно туда что-то писать. До момента старта программы UB нет.
Вы просто пессимист. Ввиду того, что UB включает в себя всё что угодно, включая валидную программу на С++, можно сказать, что любая программа с UB написана на С++ :)
Да, но не сказано ГДЕ нужно это сделать. Я могу это сделать в любом TU в программе. Это никак не меняет того факта, что если я разместил какой-то int где угодно в программе по адресу 0x3 и этот int всё еще там, пока я пишу в адрес 0x3 - это абсолютно валидный код, ничего не нарушающий, не создающий UB, и т.д. и т.п.
В С++ нет ничего синтаксически некорректного в желании записать что-то по любому адресу. Стандарт говорит: "Если по этому адресу лежит то, что ты туда пишешь, то всё нормально". А вот если "там лежит не то, что ты туда пишешь" или "там ничего не лежит", то тут UB.
Но я же могу подключить её в С++? Вся эта магия - она в макросах, так что существует в заголовочном файле.
В таком случае никто в Embedded в принципе не программирует на С++)