LINUX.ORG.RU

LLVM. Зачем он вообще нужен?

 ,


3

6

Я понимаю, зачем его используют: чтобы не писать 100500 раз в каждом компиляторе одни и те же алгоритмы оптимизации.

Я не понимаю, почему не использовать просто компиляцию через Си или Си++. Оптимизации сделает компилятор Си. Семантика у LLVM всё равно совпадает с Си, по объёму кода компилятора тоже выигрыша практически нет. Зато если использовать Си, можно использовать любой из компиляторов Си и компилировать для платформ, для которых нет реализации LLVM.

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

что такое «философия языка»?

В Си возможность программиста использовать низкоуровневые конструкции важнее надёжности. Там не будет обязательного сборщика мусора или какого-то обязательного встроенного механизма контроля ошибок, например. Программист может сам их приделать, если хочет. В этом философия.

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

Что такое «низкоуровневые конструкции»?

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

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

В Си возможность программиста использовать низкоуровневые конструкции важнее надёжности.

Расскажи мне о низкоуровневых конструкциях в Си. Где они?

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

Это всё не низкоуровневые конструкции. Хуже того, ты можешь сырые указатели долбить почти в любом говноязычке включая Rust и даже Haskell.

Там не будет обязательного сборщика мусора или какого-то обязательного встроенного механизма контроля ошибок, например.

Всё это не делает Си низкоуровневым. Это делает Си просто крайне убогим языком. Ты бы ещё про Brainfuck и его философию тут рассказал, в нём ведь даже синтаксиса нет!

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

Всё относительно. Например, я считаю Rust тоже низкоуровневым по сравнению с Java или Python. В высокоуровневых языках тоже можно использовать сырые указатели, но это будет не так удобно и просто как в Си.

Ты бы ещё про Brainfuck и его философию тут рассказал

Уверен, что и у него есть философия. Но это не ко мне. На форуме есть любители - может они расскажут.

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

возможность выхода за границы массива

А где этого нет?

арифметика без контроля переполнения

А где этого нет?

использование юнионов

А где этого нет?

goto

goto это flow control, и он есть даже в питоне: https://github.com/snoack/python-goto

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

Считаю более высокоуровневыми языками те, с которыми могу лучше сосредоточиться на предметной области, а не запинаться об особенности языка и железа. В этом смысле 1С можно считать более высокоуровневым, чем Java и даже Python.

Признаками высокоуровневых языков может быть сборщик мусора, полноценная система исключений и нормальное ООП. В Расте этого нет. Там есть какие-то альтернативы, но они неполноценны, так как заставляют бороться с языком, а не думать о предметной области. В C++ этих признаков тоже нет. Ну может только ООП (фанаты какого-нибудь Смоллтолка за такие слова растерзают, но на то они и фанаты).

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

А где этого нет?

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

Если любите придираться к деталям, если за деревьями леса не видите, то лучше идите в юристы. Может быть пропадает блестящий адвокат.

Что касается goto, то в Питоне его нет и он не нужен. То что кто-то его прикрутил показывает только то, что он шутник. Это просто что-то типа первоапрельской шутки.

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

В высокоуровневых языках за всякие фокусы с выходом за границы и переполнением прилетит исключение, с подробной информацией где и что ты нарушил.

Выход за границы массива… UB. Так что в си выхода за границы масси как раз нет :))))

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

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

Ну окей. Brainfuck – это высокоуровневый язык или нет? Я серьёзно спрашиваю.

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

объективно в си нет массивов ( как и в питоне переменных - есть имена на объекты)

«Си-массив» это синтаксический сахар на мономассив с заданым размером элемента и смещённой базой

по факту если нет защиты по памяти

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

т.е. в Сяшке указатель первичен - а индексность относительно типизированной вешки - синтаксический сахар более съедобный алгол(фортран_пл и проч проч)0пришельцам

Сяшка это асм - за то и

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

goto в Питоне нет во входном синтаксисе

и согласно тавтологии Бёма-Якопине оно излишне

при этом приведённый пример его прикручивания через декоратор - годный пример реализации прикручивания семантики

во времена оные был отладчик с обращениями к нему через d||

тем и полезен Питон - что наряду с песочницей есть способы прикручивания семантики

но Питон не требует как С++(и тем более Java) постоянно соблюдать ритуал прикручивания семантик

высокоуровневость это по началу маркетинговость подчёркивающая что менеджеру на Коболе/Бэйсике нЕ нужно регистрами обмазываться

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

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

в С(истянно святом) - есть только мономассив - это всё то что читаемо/писуемо через 0[смещение] остальные «массивы» это вешки баз

Ахаха еще один не осилил прочитать стандарт. Сейчас ты путаешь указатель и массив. Это разные вещи. Ну и да — если результат смещения вышел за границы ссылаемого массива, то это тоже ub.

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

будь внимательней!

стандарт это для прикрытия жЁп

исторически сложилось что другого общего асма не нашлось кроме как си (ибо Юникс как универсальный пользовательский интерфейс показалось вкусным - пока wintel не за колосился)

в Си нет массивов(ты сам UB обозначил из стандарта как ожидаемое когда нарушается «декарация» массива) есть указатели

массив в языке это когда код при исполнении выдаёт не UB а детерминированное поведение при нарушении интерфейса

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

Предлагаю обсудить, а как так получилось, что в стандарт вообще завезли UB? Ну это же кек, столько умников писало и такие - а вот тут мы рыбу заворачиваем.

Что мешало определить поведение явно указав определённые правила (да хоть кода ошибок и аварийный останов) как например указывают правила и порядок приведения типов?

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

Obezyan
()
Ответ на: комментарий от qulinxao3

в Си нет массивов(ты сам UB обозначил из стандарта как ожидаемое когда нарушается «декарация» массива) есть указатели

Ещё раз: в C есть отдельно указатели и отдельно массивы. У них даже семантика разная: массив нельзя копировать, его нельзя передавать по значению, массив имеет границы, которые компилятор проверяет и дает тебе по морде если ты выходишь за эти границы (привет stack protector). Это разные сущности. То, что ты про это не ознаешь, просто означает, что ты не знаешь C.

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

ещёразасть это чьята «быть тугим»

в К&R(свят свят) указатель унд аррэй - одна глава

в постстандартную эпоху в tCpl ANSI/ISO/Standard approved - ужо несколько

и конечно семантика различна ибо комитет признал компиляторы разных вендоров годными а других ой-нет

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

ибо стандарт постфактум

в Си нет массивов есть сахар что бы пришелцы в указатели с первых же минут не втыкались - как результат работы хватит на много поколений вперёд ибо по забагованности С-код один из лидеров ибо знание синтаксиса не гарантирует почти ничего

какой такой чекер границы? оно явно опционально ибо без рантайма животворящего как? — зерокост не позволит чек границы

а статическое NP-(а скорее тьюринг) полно

расскажи С-писатель как вы там достигли нирваны протектируя стек!

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

UB это следсnвие унифицирующей политики уже наличных в дикой природе разросшихся реализаций за 10 лет между взрывом распространения K&R и наконец-то принятием стандрата (они не смогли в 1985 ибо тогда бы то что стало потом плюсами попало бы в стандарт - imho)

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

унижаешь в своей голове моё (мужское) достоинство

ок.

зы. умалять чьё-либо (мужское) достоинство,

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

Предлагаю обсудить, а как так получилось, что в стандарт вообще завезли UB?

Тут нечего обсуждать - стандарт это общий делитель разных аппаратно-программных платформ. Разумеется, весь остаток от деления пошёл в UB. Плюс он писался задним числом. Моменты типа с кавычкой результат буквально двух существовавших реализаций с разным поведением.

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

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

Это понятно, вопрос в другом. Доколе? Сколько десятков лет нужно чтобы стереть это грязное пятно из стандарта?

Obezyan
()
Ответ на: комментарий от monk

И это тоже понятно, но - неправильно, буквально - ненадежный стандарт.

Скорость в ущерб надёжности в низкоуровневом языке…

Это, если посмотреть не зашоренным взглядом с критическим мышлением - не стандарт (и язык) , а какой-то кек.

Стандарты же на то и стандарты что чётко определяют как и что, разве нет? Наличие UB делает из стандарта в лучшем случае - методические рекомендации.

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

Скорость в ущерб надёжности в низкоуровневом языке…

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

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

Стандарты же на то и стандарты что чётко определяют как и что, разве нет?

Для этого стандарты должны опираться на непротиворечивую теорию. А теориями, тем более непротиворечивыми, занимаются академики. Тебе нужен академический язык, который построен на основе теории (coq, agda и brainfuck, дада)?

Не говорю о том, чтобы железо тоже было построено на основе непротиворечивой теории, а не эти с виртуальной адресацией, с ring(-2), dma и прочей смесью архитектур фон Неймана, Гарварда и непонятно чего.

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

Доколе? Сколько десятков лет нужно чтобы стереть это грязное пятно из стандарта?

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

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

Стандарты же на то и стандарты что чётко определяют как и что, разве нет?

Да, в какой-то одной чётко очерченной области.

Наличие UB делает из стандарта в лучшем случае - методические рекомендации.

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

Уб - это норма для стандарта. Вот, возьмём к примеру стандарт на IP rfc791:

Address Formats:

      High Order Bits   Format                           Class
      ---------------   -------------------------------  -----
            0            7 bits of net, 24 bits of host    a
            10          14 bits of net, 16 bits of host    b
            110         21 bits of net,  8 bits of host    c
            111         escape to extended addressing mode

      A value of zero in the network field means this network.  This is
      only used in certain ICMP messages.  The extended addressing mode
      is undefined.  Both of these features are reserved for future use.

Видишь, extended addressing mode ? Он undefined. Это значит, стандарт про него ничего не говорит, и ты, не нарушая стандарт, можешь использовать этот режим для своих целей.

Вот, @hateyoufeel, например, при получении пакета с такой адресацией выведет себе на экран гигантский член.

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

Видишь, extended addressing mode ? Он undefined. Это значит, стандарт про него ничего не говорит, и ты, не нарушая стандарт, можешь использовать этот режим для своих целей.

Нет, не можешь. Потому что в следующем стандарте он будет определен и твоя срань начнет работать неправильно. Для того что ты хочешь, используется понятие «vendor-specific».

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

Потому что в следующем стандарте он будет определен

  1. Или не будет.
  2. Я по-прежнему буду соответствовать прежнему стандарту, ЧТД.

Для того что ты хочешь, используется понятие «vendor-specific».

Нет, не используется. «vendor-specific» используется прямо в тексте стандарта тогда, когда стандарт прямо описывает механизм расширений для вендоров.

То, что «хочу я», называется «использование недокументированных возможностей».

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

Или не будет.

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

Я по-прежнему буду соответствовать прежнему стандарту, ЧТД.

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

Нет, не используется. «vendor-specific» используется прямо в тексте стандарта тогда, когда стандарт прямо описывает механизм расширений для вендоров.

Ага, это как раз то, что ты делаешь.

То, что «хочу я», называется «использование недокументированных возможностей».

То что делаешь ты, называется «быдлокодерство».

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

Я по-прежнему буду соответствовать прежнему стандарту, ЧТД.

Ты по-прежнему не будешь ему соответствовать.

Назови нарушенный пункт стандарта.

То что делаешь ты, называется «быдлокодерство».

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

Это буквально то, на что надеются сишники с UB.

Ох, лол. Сишники фактически не могут написать программу, которая бы не имела UB. Как ты с такими познаниями в предмете вообще вкатился в этот тред?

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

Назови нарушенный пункт стандарта.

Ты используешь зарезервированные поля. Ты сам дойдешь до словаря или мне рассказать тебе что значит «зарезервированный»?

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

Киса ты что обиделась?

Ох, лол. Сишники фактически не могут написать программу, которая бы не имела UB.

Ты просто не шаришь:

#include <stdio.h>

int
main(void)
{
    puts("LamerOk не шарит");   
    return 0;
}

Показывай UB.

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

Мне кажется, ты чего-то не понял. Стандарт спроектирован с наличием грязного пятна.

Я действительно не понял почему сделали грязное пятно вместо явного бросания ошибок/исключений и почти 40 лет все делают вид что так и надо.

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

zero cost (тогда) всему виной

у си фактически нет рантайма(обязательного) всё что есть опцинально

ибо асм для всех железок такой самый подходящий

а ща легаси да и миллион мартышек уже привыкли к такому варианту «тут так принято» - более того зачем менять «латынь» если полно новых_языков

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

The extended addressing Mode is undefined. Both of these features are reserved for future use.

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

Obezyan
()
Ответ на: комментарий от LamerOk

Исправляй UB.

Зачем ты это породил и что ты пытаешься этим доказать? Что ты не умеешь писать сишный код или пользоваться флагами компилятора, чтобы превратить это в человеческий врапинг?

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

неопределённость в американских стандартах оставляли для уточнения в следующих итерациях

Нет, не всегда. В случае с Си - точно нет.

почему сделали грязное пятно вместо явного бросания ошибок/исключений и почти

Потому что стандарт языка не написан для разработчиков языка. Стандарт написан для разработчиков компиляторов. А для программистов на языке написана документация к их целевому оборудованию и компилятору + бибилиотекам. Стандарт им нужен только для поиска бага в последних.

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

Назови нарушенный пункт стандарта.

Ну он прав в том что если используется то что находится ВНЕ стандарта то результат никак не будет ему соответствовать. Тоже самое с UB.

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

Сишники фактически не могут написать программу, которая бы не имела UB.

Зачем ты это породил и что ты пытаешься этим доказать?

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

Киса ты что обиделась?

Нет, киса думает, стоит ли дальше отвечать на твой тупняк. Я даю тебе шанс:

ты не умеешь писать сишный код

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

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

то что находится ВНЕ стандарта то результат никак не будет ему соответствовать.

Соответствовать стандарту == не нарушать его требований. Только и всего.

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

zero cost (тогда) всему виной

все в округе говорили,
этой странной UB,
этой странной UB,
так ему и не простили...

Скорее всего вы правы и именно это было причиной. Но, что сейчас? По-прежнему ли это оправдано? Или тут как с заповедями?

Obezyan
()
Ответ на: комментарий от LamerOk

Соответствовать стандарту == не нарушать его требований. Только и всего.

Если стандарт говорит - вот это вот будет UB, а программист использует, это не нарушение? (это кстати краеугольный камень непонимания логики)

Obezyan
()
Ответ на: комментарий от LamerOk

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

Я не собираюсь разбираться в том что хотел сказать автор. Либо ты пишешь, что хочешь сказать, либо мечешься по форуму и орешь что тебя никто не понимает. Pick your poison.

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

<stdckdint.h>

or

-fwrapv

Остальное пережитки прошлого и не нужно.

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

Соответствовать стандарту == не нарушать его требований. Только и всего.

Ты их нарушил, начав использовать зарезервированные поля. Завтра выйдет новый RFC, куда напишут «если бит N выставлен, значит автору надо послать вагон резиновых членов за его счет». И все, и ты в долговой яме заваленной резиновыми членами.

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

Brainfuck – это высокоуровневый язык или нет?

Низкоуровневый. В принципе, он не сильно от ассемблера отличается. Набор команд только очень маленький и не привязан к какой-то конкретной машине.

Kogrom
()
Ответ на: комментарий от qulinxao3

в си нет массивов… «Си-массив» это синтаксический сахар…

Память то под этот «массив» выделяется. Так что это не просто указатель. Но перемещение по этому «массиву» программой не контролируется, да. Операционный системе может не понравиться, что мы лезем в чужую память и она прервёт выполнение программы. Но это уже другой вопрос. Да и не везде ОС есть.

Kogrom
()
Ответ на: комментарий от Obezyan

Если стандарт говорит - вот это вот будет UB, а программист использует, это не нарушение?

Ещё раз медленно и печально - вот программа на Си, которая приводит к UB.

И нет, это не нарушение. Нарушить стандарт можно только создав комплиятор, который нарушает требования стандарта. Потому что стандарт на реализацию языка Си и его библиотеки, а не на «программы написанные на Си». Программист не может «нарушить стандарт» в процессе написания программы, отличной от тулчейна Си-языка.

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

int add(int a, int b)

Я когда-то использовал информацию по ссылке. Но иногда это излишне. Например, у нас прошивка микроконтроллера считает скользящее среднее по данным АЦП. Мы знаем, что это АЦП выдаёт от 0 до 255. Соответственно, мы можем сказать, что сумма из 4, например, замеров не переполнит 16-битное целое. Контроль переполнения не нужен.

Kogrom
()
Ответ на: комментарий от LamerOk

@hateyoufeel случайно не приходится тебе родственником?

Думаешь у нас семейная монополия на шутки про члены? Патентованые членовые скоморохи? Раскусил. Теперь с каждой членошутки ты нам должен платить роялти. Не заплатишь — отправишься в яму.

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

Тогда почему вы не используете uint8_t, лол?

uint8_t для суммы тоже, вероятно, можно использовать. Просто алгоритм сложнее будет. Либо в точности проиграем. С uint16_t проще и быстрее.

Kogrom
()
Ответ на: комментарий от qulinxao3

array это не массив, это «куча». То есть свалка данных на стеке либо в памяти с условными границами. Это не синтаксический сахар.
Массивы в си предполагается что ты напишешь сам как нибудь вот так:

#define arr_begin(a) &a.buf[0]
#define arr_end(a)   &a.buf[a.size]

struct arr {
    char buf[255];
    int size;
}

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

вот вот COMMON BLOCK as is

всёж сяшка не с неба упало там фортран все умели

токмо прогресс есть поэтому вот эти именованные комонблоки не только статик в глобальных; но и на стеке динамично; ну а ежель какой m(памяти)alloc(датель) есть так чистый сахар

т.е. как и весь С(плод гения РичиТомсона) набор не ортогональных эвристик и адхоков приспособленных для переноски ядра расширенной машины

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

объективно в си нет массивов

А где есть? Семантика

char *s;

и

char s1[100]

заметно отличается. s и s1 не взаимозаменяемы.

Сяшка это асм - за то и

Нет. В асме нет UB.

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

Сяшка это переносимый асм поэтому та часть которая заведомо общая у тех обычных процов - то детерменированно в сяшке то что платформо обусловленно частично UB

не будь уже устоявшегося протокола установления остро-тупо-конечности или вообще перемешаные байта в 4байтовом слове - это тоже было бы UB

и если уж совсем лезть в дебри - на процах есть UB - недокументированные команды наличие которых не гарантированно

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

Сяшка это переносимый асм

Сишка настолько сильно не в контексте современного железа, что уже даже не смешно. Мы, напомню, до сих пор кешлинии руками считаем.

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

на процах есть UB - недокументированные команды наличие которых не гарантированно

И в чем здесь UB? У тебя либо выполнится команда, либо процессор скажет тебе, что ты баклажан.

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

то детерменированно в сяшке то что платформо обусловленно частично UB

Нет. Есть UB не от платформы.

Например:

int data[10];

int find(int x)
{
  int i;
  for(i = 0; i <= 10; i++)
    if(data[i] == x) return 1;
  return 0;
}

На любом ассемблере

find(1) && find(2) && find(3) 
  && find(4) && find(5) && find(6)
  && find(7) && find(8) && find(9)
  && find(10) && find(11) && find(12) == 0

потому что в data[0]…data[10] всего 11 значений, а значит find хотя бы для одного из 12 значений должен вернуть 0. Но на Си он будет возвращать 1 для всех значений.

monk ★★★★★
() автор топика
Ответ на: комментарий от monk
int data[10];
...
for(i = 0; i <= 10; i++)

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

Но на Си он будет возвращать 1 для всех значений.

?

LamerOk ★★★★★
()
Ответ на: комментарий от monk
#include <stdio.h>


int data[10];

int find(int x)
{
  int i;
  for(i = 0; i <= 10; i++)
    if(data[i] == x) return 1;
  return 0;
}


int main ()
{
  int a = ((find(1) && find(2) && find(3)
	   && find(4) && find(5) && find(6)
	   && find(7) && find(8) && find(9)
	   && find(10) && find(11) && find(12)) == 0);

  printf("= %d\n", find(1));
  printf("= %d\n", find(2));
  printf("= %d\n", find(3));
  printf("= %d\n", find(4));
  printf("= %d\n", find(5));
  printf("= %d\n", find(6));
  printf("= %d\n", find(7));
  printf("= %d\n", find(8));
  printf("= %d\n", find(9));
  printf("= %d\n", find(10));
  printf("= %d\n", find(11));
  printf("= %d\n", find(12));


  printf("%d\n", a);
}

= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
= 0
1

nionio35
()
Ответ на: комментарий от LamerOk

Во первых у тебя выход за границы массива.

Да.

Во вторых я не понял, что ты пытался сказать.

Что чтение за границей массива на любом ассемблере или вернёт определённое число или аварийно завершит программу. Повторное чтение вернёт то же самое число.

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

Но на Си он будет возвращать 1 для всех значений.

https://godbolt.org/z/dv1nKM99T

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

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

Идеальный пример - это же буквально подмена понятий и спекулятивная интерпретация.

Компилируемый язык (вернее компилятор) на глазах у всех занимается интерпретацией. Тот же бег в темноте со столбами как, например, спекулятивное предсказание выполнения инструкций в процессорах.

Разве кому-то здесь не очевидно что попытка чтения за границей массива должна вызывать явное исключение/ошибку?

А потом все удивляются зачем всякие Go для ширнармасс создают.

Obezyan
()
Ответ на: комментарий от monk

Но на Си он будет возвращать 1 для всех значений.

https://godbolt.org/z/dv1nKM99T

clang со любыми оптимизациями (000000000000=1) https://godbolt.org/z/Y4fdzrTjr

gcc -O0 (000000000000=1) https://godbolt.org/z/Gn97vzcss

gcc -O1 SIGSEGV https://godbolt.org/z/qoKnW1csG

gcc -O{2,3,fast} твой случай

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

Низкоуровневый. В принципе, он не сильно от ассемблера отличается. Набор команд только очень маленький и не привязан к какой-то конкретной машине.

От какого именно ассемблера? Ассемблер для какого-нибудь студенческого OISC и ассемблер со встроенным ООП для iAPX432 – это разные ассемблеры.

Что именно в твоём понимании делает Brainfuck низкоуровневым? Является ли нетипизированное лямбда-исчисление низкоуровневым в твоём понимании? Там тоже «команд» мало.

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

Повторное чтение вернёт то же самое число.

если это очевидно не отображённые на память порты ввода например

али ещё что конкурентное (сори но даже возврат того же самого гарантирован не на всём универсуме ассемблеров :) )|

по коду - а как ща (и везде ли и с какого ) глобальный массив как инитится ежель нет явного заброса байт

ты вот этот код как пример чего ?!?

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

если это очевидно не отображённые на память порты ввода например

Даже в этом случае возвращённое число не всегда будет равно аргументу функции.

ты вот этот код как пример чего ?!?

Что в Си в случае чтения за границей массива может быть истинно ∀x: a[10] == x. А для ассемблера оно будет иногда ложно.

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

какой тезис по коду то?

по кроликам дирихле a достоверно(если data конкуренто не массируют что бы в 0-9(ой 10 тоже) ячейках обнаружились все 12 варианто) 1

чёйта както :

летело два каркадила один зелённый второй на лево

искренне хочу обрести такую лёгкость программирования

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

UB - может делать что угодно, например, генерировать програмное/аппаратное исключение (SIGSEGV), обработчик которого может отформатировать диск.

Это как раз нормально. UB как произвольное действие — это как раз семантика ассемблера.

Но в Си программа переписывается с целью устранения UB. В результате, например, эта программа никогда не упадёт, даже если сразу за массивом data данные чужой программы. Потому что массив data вообще не читается.

monk ★★★★★
() автор топика
Ответ на: комментарий от qulinxao3
int find(int x)
{
  int i;
  for(i = 0; i <= 10; i++)
    if(data[i] == x) return 1;
  return 0;
}

Компилятор Си видит, что data[10] за концом массива. Значит в цикле i не может достичь 10, значит гарантированно в одном из предыдущих элементов должен отработать return 1.

И меняет код на оптимизированный:

int find(int x)
{
  return 1;
}
monk ★★★★★
() автор топика
Ответ на: комментарий от monk

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

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

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

возможно ваш тезис и верен

но вот этот код както мне не очевидно доказывает ваш тезис:

1. проверятся на наборе(массив из N элементов по факту N+1 значение <- если это не важно для тезиса можно s/<=10/<10/ ?!)

затем на N+1 значении проверяется N+2(различные) пробы -> кролики дирихле вымерли

очевидно одна из проверок будет 0

битовое произведение проверок 0

как истиность тезиса подтверждается фактом что разных проб больше чем множество значений в data + ещё элемент ?!?

реально доставили

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

В стандарте написано, что программа, содержащая UB может делать что угодно. В данном случае «что угодно» = «считаем прочитанные данные равными x».

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

давай пусть data[2] или даже data[1]

c соответсвующем сокращением трасы и проверяемых значений:

позязуся (можно запринтить ) покажи трассу и состояния локальных

ну или сам с карандашём протрасируйся

имхо как то сказачно вот это вот всё - а ведь ещё даже не пятница

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

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

В стандарте написано, что программа, содержащая UB может делать что угодно.

Подожди-подожди. Ты искренне надеешься, что я не замечу подмены тезиса?

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

как истиность тезиса подтверждается фактом что разных проб больше чем множество значений в data + ещё элемент ?!?

Переданное значение (проба) должно быть равно какому-то значению из data + ещё один элемент. Если передано больше разных проб, чем множество значений, то хоть одна проба должна не попасть во множество значений.

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

может быть и так

однако тут не важно ибо мощьность множества значений (data + следующее значение) заведомо меньше чем длина(data) +2

т.е если код не упадёт то a всегда 1

какое это отношение к UB!?!

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

Так ты отказываешься защищать свой тезис

А на Си чтение за границей массива воспринимается как то, что условие, при котором этого чтения нет, гарантированно истинное.

?

Что угодно включает в себя изменение кода на такой, при котором чтения нет.

Это уже другой тезис. Ты готов его защищать цитатами из стандарта? Или опять будет игра в напёрстки?

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

т.е если код не упадёт то a всегда 1

a = "в множестве есть 1" и "в множестве есть 2" и ...

Если хоть одного из чисел 1..12 в множестве нет, то a = 0 (ложь).

какое это отношение к UB!?!

А UB позволяет в множестве из 11 элементов увидеть, что есть 12 разных значений.

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

Что угодно включает в себя изменение кода на такой, при котором чтения нет.

Это уже другой тезис. Ты готов его защищать цитатами из стандарта? Или опять будет игра в напёрстки?

В стандарте написано «что угодно». Изменение кода работающей программы включено в понятие «что угодно» по определению понятия «что угодно».

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

В стандарте написано «что угодно». Изменение кода работающей программы включено в понятие «что угодно» по определению понятия «что угодно».

Подожди-ка, сейчас твой тезис уже трансформировался в «UB даёт непредсказуемый результат».

Ты точно хочешь выразить какую-то логически связанную мысль?

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

хз почему копулятор сверхоптимизировал

вообще тут это не причём

твой исходный код(начальный на который ?)

произведение 12 битовых проверок всегда будет тождественно 0 - это твоё исходное утверждение(тезис) ?

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

произведение 12 битовых проверок всегда будет тождественно 0 - это твоё исходное утверждение(тезис) ?

Математически это так. Для семантики ассемблера (в которой ячейки памяти имеют определённые значения) это так.

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

по стандарту али «тут так принято»?

В стандарте нет ни одной запятой про оптимизацию. Но стандарт позволяет одной и той же программе, полностью ему соответствующей и даже не имеющей никакого UB, выдавать разные численные результаты (на разных платформах, компиляторах, опциях). В стандарте Си нет гарантий на идентичность вычислений между реализациями. Разумеетcя, для программ с UB всё это тоже применимо.

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

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

В стандарте Си нет гарантий на идентичность вычислений между реализациями.

Частичная есть. На целочисленные в рамках значений попадающих в минимальный диапазон для типа.

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

не сообщая(остовляя при ебе ) своё мнение об истинности вот этих двух ваших тезисов(сложносоставленных из двух абзацев первый о стандарте и второй о наблюдении за людьми ...)

как это помогает отрефлексировать и уяснить как monk пришёл к такому выводу - его модель отражающее поведение его кода

.

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

Частичная есть. На целочисленные в рамках значений попадающих в минимальный диапазон для типа.

Внезапно, нет. Там нет явных требований на результат операций, и сложение двух единиц в полном соответствии со стандартом может дать 3. Минимальная размерность лишь гарантирует минимально допустимый диапазон значений переменных встроенных типов.

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

Значит в цикле i не может достичь 10,

Но ведь может, это явно указано в условии цикла for (i <= 10)

значит гарантированно в одном из предыдущих элементов должен отработать return 1.

В том то и дело что не должен. Компилятор прячет ошибку вместо сигнализирования о ней. И это считается нормой. И к тому же оч коряво прячет, после этой «оптимизации» find(11) тоже вернёт 1.

Obezyan
()
Ответ на: комментарий от LamerOk

комплиятор выкинет часть написанного кода.

Компилятор в данном случае выкинет буквально всю суть логики работы программы. Зато бегает быстро, до первого столба.

Obezyan
()
Ответ на: комментарий от LamerOk

Там нет явных требований на результат операций, и сложение двух единиц в полном соответствии со стандартом может дать 3.

Есть. 6.5.6.

The result of the binary + operator is the sum of the operands.
monk ★★★★★
() автор топика
Ответ на: комментарий от monk

И только. Причём этот пункт воткнут не из желания прописать семантику сложения в си, а с целью упрощения объяснения приведения типов и адресной арифметики дальше в тексте стандарта.

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

Но этот пункт всё-таки не даёт на 1 + 1 вернуть 3. Если у вас в стране не альтернативная математика.

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

Ты хочешь доказать, что в стандарте есть гарантии на результат матвыражений?

6.5.5

6
When integers are divided, the result of the / operator is the algebraic quotient with any
fractional part discarded.
If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is
undefined.

Вот тебе два оператора, в отношении которого прямо сказано - «сделайте как хорошо, не получится? Ну, как сумеете.»

Фактически использование любого из этих операторов согласно тексту стандарта == UB.

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

Ты хочешь доказать, что в стандарте есть гарантии на результат матвыражений?

На некоторые есть.

Вот тебе два оператора, в отношении которого прямо сказано - «сделайте как хорошо, не получится? Ну, как сумеете.»

Нет. Тут всё однозначно. Результат «algebraic quotient with any fractional part discarded». Но результат может не попадать в нужный тип INT_MIN/(-1) например не «is representable», а значит UB.

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

Что именно в твоём понимании делает Brainfuck низкоуровневым?

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

новые бессмысленные вопросы

Так как эти вопросы не принесут мне никакой пользы, то не вижу смысла их обсуждать.

Kogrom
()
Ответ на: комментарий от monk

Тут всё однозначно.

Ага. Пополняем список операторов, содержащих UB:

int add(int a, int b)
{
     return a + b;
}
int div(int a, int b)
{
     return a / b;
}
int reminder(int a, int b)
{
     return a % b;
}
int shift_left(int a, int b)
{
     return a << b;
}
int shift_right(int a, int b)
{
     return a >> b;
}
LamerOk ★★★★★
()
Ответ на: комментарий от nionio35

В других языках или всё отдаётся на волю операционной системы (ассемблер, форт, …) или происходит явная проверка (паскаль, лисп, …).

На самом деле, это сделано, как и любое UB, чтобы можно было выкидывать ненужные операции.

int data[10];

int test2(int n)
{
  if(n < 20) return 1; else return 2;
}

int test(int n)
{
  if(data[n] > 0 && test2(n) < 2) return 1;
  return 0;
}

Здесь функция test оптимизируется до

int test(int n)
{
  if(data[n] > 0) return 1;
  return 0;
}

потому что, если мы смогли прочитать data[n], значит 0 <= n < 10 и test2(n) всегда равен 1.

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

На самом деле, это сделано, как и любое UB, чтобы можно было выкидывать ненужные операции.

При UB «нужность» операции теряет смысл, теряет семантическое значение: можно удалять, дополнять, заменять - семантика программы на СИ не изменится.

Поэтому твою «программу с UB» gcc компилирует по разному:

  • при -O0 - как ожидает человек, не заметивший UB
  • при -O1 - как ожидает человек, заметивший UB
  • при -02 и выше - как не ожидает человек
anonymous
()
Ответ на: комментарий от monk

Пополняем список операторов, содержащих UB

… при некоторых значениях аргументов.

Ты берёшься формально доказать в отдельно взятом юните трансляции, что аргументы укладываются в допустимые диапазоны? Потому что если нет - то это UB. Прямое, простое и бесхитростное, прямо прописанное в стандарте.

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

Ты берёшься формально доказать в отдельно взятом юните трансляции, что аргументы укладываются в допустимые диапазоны?

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

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

не выходит за массив, значит всегда там 1. а если 0 > n >= 10 так ты хочешь прочитать то что нельзя.

Да, но нет. В оптимизаторе НЕТ той логики, что monk пытается изложить и ты видишь. Оптимизатор просто попытался вычислить в константные значения отдельные ветки кода. На более крупной цепочке более сложных вызовов та же самая оптимизация может не сработать. У тебя нет гарантии, что компилятор по коду везде сделает такие замены.

Повторюсь (раз тред никто не читает), это не семантика языка программирования, это эвристика оптимизации конкретного компилятора.

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

аргументы укладываются в допустимые диапазоны? Потому что если нет - то это UB

UB - когда во время выполнения вылезешь за допустимые диапазоны (по факту, а не по «недополученной прибыли»)

Иначе все прогаммы - UB и форматируют диск

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

Именно это ожидается от ответственного программиста.

И ты, конечно же, можешь привести в пример хоть один реальный программный продукт с доступным кодом, где мы можем это увидеть на каждой операции?

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

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

Так нет гарантии, что оптимизация вообще хоть какая-то будет. Оптимизация может быть, а не обязана быть.

это не семантика языка программирования, это эвристика оптимизации конкретного компилятора

Это как раз семантика. Вот такая же семантика, привязанная к конкретной функции, а не набору UB: https://doc.rust-lang.org/std/hint/fn.unreachable_unchecked.html

if (x > 0) { f(x); } else { std::hint::unreachable_unchecked(); } 

компилятор вправе сократить до вызова f(x) и внутри функции быть уверенным, что x положительный.

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

Так нет гарантии, что оптимизация вообще хоть какая-то будет. Оптимизация может быть, а не обязана быть.
Это как раз семантика.

Ты сам себя не пробовал прочитать? Что это за «семантика» языка программирования, которая может быть, а может и не быть? Это семантика мигалки, чтоле?

компилятор вправе

Не-не-не, девид блейн. Ты сейчас притащил натуральную #pragma unreachable из вообще другого языка программирования в доказательства своего тезиса о Си. Это так не работает.

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

Так любой достаточно старый, какой ни возьми.

Например, https://github.com/torvalds/linux/blob/master/crypto/aead.c#L272

Программист проанализировал, что count при вызове точно не равен INT_MIN, а значит UB в этом арифметическом действии не происходит.

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

Что это за «семантика» языка программирования, которая может быть, а может и не быть?

Нормальная семантика. В лиспе такое тоже есть.

(eq 3.0 3.0)
=>  true
OR=>  false

И вообще, почти в любом языке. Когда для каких-то операций при каких-то аргументах допустим любой результат. Си тут выделился только тем, что когда-то в стандарте вместо «неопределённое значение или аварийный останов» вписали «неопределённое поведение» и это позволило сделать оптимизирующие компиляторы, который для правильных (не приводящих к UB) программ генерируют наиболее быстрый (или близкий к нему) исполняемый код.

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

x передается по значению или по ссылке?

Есть разница?

если в другом потоке значение x меняется?

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

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

Нормальная семантика.

Приехали.

В лиспе

Это многое объясняет. Давай-ка я в рамках гуманитарной помощи лисп-сообществу помогу тебе сформулировать твой тезис и озвучу свой контр-тезис.

Эта ветка срача началась с

Есть UB не от платформы.

После двух увлекательных дней, мы можем, наконец-то, озвучить твой тезис полностью:

Ты утверждаешь, что некоторое UB, позволяющее компилятору модифицировать целевую программу, является частью семантики языка си.

Я утверждаю, что семантика си ограниченна содержимом стандарта, и при наступлении UB компилятор игнорирует описанную в стандарте семантику. Таким образом, любые производные от UB оптимизации частью семантики си не являются по определению.

Предлагаю тебе переформулировать твой тезис и/или оспорить мой.

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

Я утверждаю, что семантика си ограниченна содержимом стандарта, и при наступлении UB компилятор игнорирует описанную в стандарте семантику. Таким образом, любые производные от UB оптимизации частью семантики си не являются по определению.

Если бы это было так, то всё, что не описано в стандарте любого языка, позволяло бы компилятору переписывать программу. Или в том же Си оптимизатор мог бы выкидывать не только явно указанный UB, но и, например, ветки с опечатками в ключевых словах (это же тоже не указано в стандарте).

Или можно было бы написать компилятор лиспа, соответствующий стандарту, с аналогичной семантикой доступа к элементам массива, как в Си. Ведь тут не указано, что может быть, если индекс за пределами массива: https://www.lispworks.com/documentation/HyperSpec/Body/f_aref.htm

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

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

Пчёл, у нас не лисп!!!111 Опечатки в ключевых словах - это синтаксически не корректная конструкция, она до оптимизатора просто не доходит.

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

Именно это мы и наблюдаем с оптимизациями при UB: раз, два.

В Си UB явно указано в стандарте.

А где последствия UB указаны в стандарте?

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

Именно это мы и наблюдаем с оптимизациями при UB: раз, два.

Это в Си/Си++. А я про то, что если бы было так, то такое встречалось бы в любом языке, на который есть стандарт. Например, в ECMAScript.

Опечатки в ключевых словах - это синтаксически не корректная конструкция, она до оптимизатора просто не доходит.

До компилятора же доходит. И в стандарте не описано, что должно при этом происходить.

А где последствия UB указаны в стандарте?

Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Вот оптимизирующие компиляторы и «behaving during translation … in a documented manner characteristic of the environment».

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

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

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

Ты явно стандарт не читал. 4-ая глава:

5
A strictly conforming program shall use only those features of the language and library
specified in this International Standard.3) It shall not produce output dependent on any
unspecified, undefined, or implementation-defined behavior, and shall not exceed any
minimum implementation limit.

Как только компилятор в ходе трансформации кода встретил UB и не прервал компиляцию, а продолжил работу - результат его работы не соответствует стандарту языка. Хуже того, даже если нигде в ходе компиляции не встретилось 100%-ого UB, то результирующая программа всё равно еще не корректна:

3
A program that is correct in all other aspects, operating on correct data, containing
unspecified behavior shall be a correct program and act in accordance with 5.1.2.3.

То есть программа на сишечке корректна, только пока пользователь вводит правильные данные. Ошибся в воде - все взятки гладки.

behaving during translation … in a documented manner characteristic of the environment

И это не является семантикой самого языка программирования си так, как он определён в стандарте. Это уже семантика environment’а, компилятора, программы КПСС, чего угодно - но не языка программирования си.

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

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

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

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

Лол, нет, это так не работает. Если в ПДД написано:

23.5. Движение тяжеловесного и (или) крупногабаритного транспортного средства, а также транспортного средства, осуществляющего перевозки опасных грузов, осуществляется с учетом требований Федерального закона "Об автомобильных дорогах и о дорожной деятельности в Российской Федерации и о внесении изменений в отдельные законодательные акты Российской Федерации".

Международные автомобильные перевозки осуществляются в соответствии с требованиями к транспортным средствам и правилами перевозки, установленными международными договорами Российской Федерации.

Это не значит, что ФЗ о дорогах и договора являются частью ПДД. ПДД и эти законы и договора сосуществуют параллельно. Семантика конкретно ПДД ограничена самими ПДД.

Ну и прямой запрет на использование UB в стандарте:

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior

ты чем будешь крыть?

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

Это не значит, что ФЗ о дорогах и договора являются частью ПДД.

Вот в этом у нас и есть разногласия. Я считаю, что в семантику (то есть смысл) ПДД входит, в том числе, и семантика упомянутого ФЗ. Потому что если этот ФЗ будет нарушен, это будет трактоваться как нарушение ПДД (п.23.5).

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior

Это ограничение подкласса программ «strictly conforming program». Если в программе нет «output dependent on any unspecified, undefined, or implementation-defined behavior», то, очевидно, эта программа будет возвращать одинаковые результаты, будучи скомпилированной любым компилятором, соответствующим Стандарту.

Но это не ограничение на действия компилятора.

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

Потому что если этот ФЗ будет нарушен, это будет трактоваться как нарушение ПДД (п.23.5).

А вот и нет. Порядок ответственности за нарушение ФЗ указан в самом ФЗ:

Глава 10. Ответственность за нарушение законодательства Российской Федерации об автомобильных дорогах и о дорожной деятельности

Статья 46. Ответственность за нарушение законодательства Российской Федерации об автомобильных дорогах и о дорожной деятельности

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

2. Действия (бездействие) органов государственной власти или органов местного самоуправления в области использования автомобильных дорог и осуществления дорожной деятельности либо должностных лиц этих органов могут быть обжалованы гражданами и юридическими лицами в судебном порядке и в предусмотренных федеральным законом случаях в административном порядке.

Ну и вообще ты бы хоть для приличия открыл ФЗ - там, например, прописаны виды собственности на дороги и порядок трат из дорожных фондов. У тебя бедный гаец всю прокуратуру заменил одним махом. Ты тут даже не сову на глобус, а фотон на сверхновую натянуть пытаешься.

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior

Это ограничение подкласса программ
Но это не ограничение на действия компилятора.

Нет. За produce отвечает компилятор, и это именно ограничение на компилятор.

Ограничения на исполнение программ в стандарте вообще нет вот по этой причине:

5. Environment
1
An implementation translates C source files and executes C programs in two data-
processing-system environments, which will be called the translation environment and
the execution environment in this International Standard. Their characteristics define and
constrain the results of executing conforming C programs constructed according to the
syntactic and semantic rules for conforming implementations.

Исходя из опыта этой дискуссии, я сразу ещё раз процитирую нужную часть по второму кругу как предварительный ответ на твой ответ к этому посту:

Their characteristics define and constrain the results of executing conforming C programs

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

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

То есть программа на сишечке корректна, только пока пользователь вводит правильные данные. Ошибся в воде - все взятки гладки.

Вы уволены.

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

Obezyan
()
Ответ на: комментарий от LamerOk

хоть для приличия открыл ФЗ - там, например, прописаны виды собственности на дороги

осуществляется с учетом требований Федерального закона "Об автомобильных дорогах и о дорожной деятельности в Российской Федерации и о внесении изменений в отдельные законодательные акты Российской Федерации"

Вот нарушен этот ФЗ, судья пишет «…водитель, управляя транспортным средством (в составе автопоезда) марки <данные изъяты> в нарушение п. 23.5 ПДД РФ,…» (https://sudact.ru/regular/doc/JKoBFMjjuKb8/)

Нет. За produce отвечает компилятор, и это именно ограничение на компилятор.

В цитате «It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior» It = «strictly conforming program». Так Вы считаете, что это компилятор должен быть «strictly conforming program»?

Their characteristics define and constrain the results of executing conforming C programs

Вы же сами пишете «constructed according to the syntactic and semantic rules for conforming implementations». Цвет автомобиля Форд-Т может быть любым, если этот цвет чёрный. Результат вычисления может быть любым, соответствующим синтаксису и семантике соответствующей стандарту реализации компилятора.

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

Порядок ответственности за нарушение ФЗ указан в самом ФЗ:

Вот нарушен этот ФЗ, судья пишет

Ты, если не понимаешь каких-то формулировок, лучше спрашивай. Потому что по твоей же ссылке:

о привлечении к административной ответственности по ч. 2 ст. 12.21.1 КоАП РФ,

КоАП - это не ПДД. ПДД - не КоАП. Водилу привлекли за нарушение ФЗ по КоАП.

Так Вы считаете, что это компилятор должен быть «strictly conforming program»?

Следим внимательно за руками: формулировка в стандарте, естественно, относится к прогону программы, но на момент запуска программы на исполнение, программа самостоятельно не может принять решение о наступлении UB, она может лишь выполнить действия, последствия которых будут UB. Остаются две точки, где на UB могли положится при создании программы - в момент написания программы и в момент компиляции. Стандарт явно запрещает оба варианта. В этом ITT-треде программистов мы не рассматриваем. Остаётся только компилятор.

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

Вот к примеру эта программа содержит UB:

#include <limits.h>
int main(void) { return INT_MAX +1; }

Если компилятор определил наличие UB, он должен либо прекратить трансляцию юнита, либо то, что он выдаст заведомо не будет strictly conforming program.

Вы же сами пишете «constructed according to the syntactic and semantic rules for conforming implementations». Цвет автомобиля Форд-Т может быть любым, если этот цвет чёрный.

Это потому что ты стандарт за эту неделю так и не осилил прочитать. Если бы прочитал, то знал, что semantic rules в сишечке описаны через некоторые свойства execution environment. Вот к примеру:

3.5
1
bit
unit of data storage in the execution environment large enough to hold an object that may
have one of two values
2
NOTE 
It need not be possible to express the address of each individual bit of an object.
3.6
1
byte
addressable unit of data storage large enough to hold any member of the basic character
set of the execution environment
...
6.2.5 Types
...
5
An object declared as type signed char occupies the same amount of storage as a
‘‘plain’’ char object. A ‘‘plain’’ int object has the natural size suggested by the
architecture of the execution environment (large enough to contain any value in the range
INT_MIN to INT_MAX as defined in the header <limits.h>).

А в отношении самого execution environment (за вычетом API и библиотек) есть лишь ограниченный набор требований на запуск и останов программы. То есть сами детали вычислений в стандарте не описаны, в стандарте описано, как сишный код должен транслироваться в формально неописанный и толком неизвестный execution environment.

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

КоАП - это не ПДД. ПДД - не КоАП.

КоАП определяет наказание. ПДД указывает, что нельзя нарушать. Не путайте. Здесь же написано

привлечена к административной ответственности по ч.2 ст. 12.21.1 КоАП РФ и назначено наказание в виде штрафа в сумме 300 000 руб. за то, что ДД.ММ.ГГГГ в <адрес> водитель, управляя транспортным средством (в составе автопоезда) марки <данные изъяты> в нарушение п. 23.5 ПДД РФ

Если компилятор определил наличие UB, он должен либо прекратить трансляцию юнита, либо то, что он выдаст заведомо не будет strictly conforming program.

Разумеется. И даже если не определил, но оно есть в тексте программы.

Если бы прочитал, то знал, что semantic rules в сишечке описаны через некоторые свойства execution environment.

Общение чем дальше, тем больше уходит в философию. «Вот эта лошадь где? Она перед тобой или в твоей голове?». Вот и семантические правила соответствующей Стандарту реализации языка Си внезапно оказываются в среде исполнения, в которой запущена скомпилированная этим компилятором программа.

Вы специально уходите в софистику или действительно пытаетесь доказать, что даже строго соответствующая Стандарту (strictly conforming) программа на Си может выдавать разные результаты в разных средах исполнения?

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

КоАП определяет наказание. ПДД указывает, что нельзя нарушать. Не путайте.

Это ты сейчас заявил, что КоАП не содержит статей о том, что нельзя нарушать? И без ПДД водилу нельзя привлечь к ответственности? Ты не пробовал перед тем, как писать что-то в интернете, сначала прочитать в нём что-то?

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

Ты сегодня с помехлюги, чтоли? Как программа может выполнить действие на основании условия, которого она не смогла определить?

действительно пытаетесь доказать, что даже строго соответствующая Стандарту (strictly conforming) программа на Си может выдавать разные результаты в разных средах исполнения?

Чувак, значение любого арифметического выражения с типами float или double совершенно не известно. И да, на разном оборудовании оно будет выдавать разные результаты. Это азы двоичной арифметики.

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

И без ПДД водилу нельзя привлечь к ответственности?

Да. Потому что в нём указаны те нормы, за нарушение которых по КоАП предусмотрена ответственность.

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

Например, если компилятор переводит a[i] в mov r1, [a+i] без какого-либо контроля допустимости указателя, а при выполнении a+i оказалось за пределами массива.

Чувак, значение любого арифметического выражения с типами float или double совершенно не известно.

F.2 Types 

The C floating types match the IEC 60559 formats as follows: 
— The float type matches the IEC 60559 binary32 format. 
— The double type matches the IEC 60559 binary64 format. 
monk ★★★★★
() автор топика
Ответ на: комментарий от monk

И без ПДД водилу нельзя привлечь к ответственности?

Да.

Ладно, дальнейшую дискуссию о КоАП я предаю в надёжные руки сотрудников ППС и дежурного в отделении. Для этого срача это уже через чур.

при выполнении a+i оказалось за пределами массива.

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

Чувак, значение любого арифметического выражения с типами float или double совершенно не известно.

Как красиво ты вырезал кусочек! Прям загляденье. А текст до и после почему пропал?

F.1 Introduction
1
This annex specifies C language support for the IEC 60559 floating-point standard. 
... An implementation that
defines _ _STDC_IEC_559_ _ shall conform to the specifications in this annex.356)

F.2 Types 

The C floating types match the IEC 60559 formats as follows: 
— The float type matches the IEC 60559 binary32 format. 
— The double type matches the IEC 60559 binary64 format. 
— The long double type matches an IEC 60559 extended format,357) else a
non-IEC 60559 extended format, else the IEC 60559 double format.

А теперь вслух и с выражением читаем ссылку мелким шрифтом:

356) Implementations that do not define _ _STDC_IEC_559_ _ are not required to conform to these
specifications.

Ссылку, я так чувствую, поставили специально для тебя. ))

В 88/89 стандарте вообще ничего про IEEE 754 и производные нет.

Ну и наконец, тривиальный же пример, без единой арифметической операции:

user@computer:/tmp$ cat size_t_size.c 
#include <stdio.h>

int main(void)
{
    (void) printf("%zu\n", sizeof(size_t));
    return 0;
}
user@computer:/tmp$ gcc -m32 -pedantic -Wall -Wextra -o size_t_size size_t_size.c 
user@computer:/tmp$ ./size_t_size 
4
user@computer:/tmp$ gcc -pedantic -Wall -Wextra -o size_t_size size_t_size.c 
user@computer:/tmp$ ./size_t_size 
8
user@computer:/tmp$ 

Предлагаю тебе найти несоответствие программы стандарту и/или доказать, что 8 == 4.

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

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

Никак. Я же именно это и утверждаю. Компилятор определить UB не может, но оно есть, а значит программа не strictly conforming.

Предлагаю тебе найти несоответствие программы стандарту и/или доказать, что 8 == 4.

sizeof(size_t) является implementation-defined behavior.

are not required to conform to these specifications.

Убедил. Любая программа, использующая вещественные числа, не strictly conforming.

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

sizeof(size_t) является implementation-defined behavior.

Ровно в том же смысле, что и диапазоны значений int или unsigned long int. Вот мы и пришли к тому - с чего начали: стандарт позволяет одной и той же программе, полностью ему соответствующей и даже не имеющей никакого UB, выдавать разные численные результаты

Поскольку, теперь мы твёрдо установили, что strictly conforming программа не может сделать сильно большего, чем сложить два плюс два, а вся арифметика у нас - это сплошной implementation-defined, который никак не documented manner characteristic of the environment, то предлагаю тебе теперь с учётом этого факта, попробовать доказать свой тезис:

некоторое UB, позволяющее компилятору модифицировать целевую программу, является частью семантики языка си.

тк по твоим словам:

В Си UB явно указано в стандарте.

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

Ровно в том же смысле, что и диапазоны значений int или unsigned long int.

Про это есть специальная оговорка «shall not exceed any minimum implementation limit». То есть

#include <stdio.h>

int main(void)
{
    int x = 20;
    int y = 22;
    (void) printf("%d\n", x + y);
    return 0;
}

является strictly conforming, так как значения не выходят за минимальные пределы, определённые Стандартом.

предлагаю тебе теперь с учётом этого факта, попробовать доказать свой тезис

Я пропустил какой-то пункт твоего доказательства. Да, программы соответствующая Стандарту, но не строго соответствующая, может возвращать разный (зависящий от реализации) результат, если использует конструкции, зависящие от реализации. Но возможность трактовать UB как «то, чего не может быть» есть только благодаря тому, что в стандарте в явном виде оно описано.

Если бы вместо UB всюду было Implementation-defined behavior или даже Unspecified behavior, то большая часть основанных на UB оптимизаций была бы невозможна.

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

Я пропустил какой-то пункт твоего доказательства.

Ты его просто не понял, а я проморгал твоё отрицание.

Про это есть специальная оговорка «shall not exceed any minimum implementation limit».

Ты покажешь, в каком месте программа:

#include <stdio.h>

int main(void)
{
    (void) printf("%zu\n", sizeof(size_t));
    return 0;
}

«exceed any minimum implementation limit» ? Потому что, если не покажешь, это - strictly conforming.

Отрицание, которое я пропустил:

Любая программа, использующая вещественные числа, не strictly conforming.

Это в общем случае не верный тезис. Программа может использовать типы с плавающей точку и быть strictly conforming:

#include <stdio.h>

int main(void)
{
    double d = 1.1;
    (void) printf("%f\n", d);
    return 0;
}

Числовые лимиты нигде не превышены, используется только стандартная библиотека, нет UB == strictly conforming.

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

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

И ты, конечно же, можешь привести в пример хоть один реальный программный продукт с доступным кодом, где мы можем это увидеть на каждой операции?

Линуксовое ядро. Все входящие от userspace параметры проверяются на соответствие диапазонам. Внутри ядра понатыканы проверки в духе «если вот эта шляпа больше допустимого значения верни ошибку». У тебя в общем-то правильно в нике про ламера написано, очень похоже.

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

В этом месте использование sizeof, про который написано, что это implementation defined.

А про double: где-то в Стандарте есть указание, что 1,1 в нëм является точным числом?

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

В этом месте использование sizeof, про который написано, что это implementation defined.

И что? В стандарте нигде не запрещается использовать implementation defined операции и типы данных. В стандарте запрещается строить поведение программы в зависимости от разницы между ними на разных платформах:

It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior.

То есть вот эта программа:

#include <stddef.h>

int main(void)
{
    size_t sz = sizeof(size_t);
    if (sz > 4)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

Не будет строго соответствовать стандарту, так как её вывод зависит от implementation defined операций.

А про double

А про double мы уже всё разобрали выше

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

не запрещается использовать implementation defined операции и типы данных

В твоей же цитате «It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior». А программа, выводящая результат sizeof, определённо produce output dependent on implementation-defined behavior.

Не будет строго соответствовать стандарту, так как её вывод зависит от implementation defined операций.

Разумеется.

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

Не будет строго соответствовать стандарту, так как её вывод зависит от implementation defined операций.

Разумеется.

Вы сейчас куда-то окончательно упоролись. Программа соответствует стандарту в том смысле, что она корректная. То, что она на разных платформах по-разному работает в зависимости от размеров типов данных не делает её менее корректной.

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

А программа, выводящая результат sizeof, определённо produce output dependent on implementation-defined behavior.

Давай уточним - ты утверждаешь, что сами выводимые диапазоны значения переменных являются implementation defined behavior?

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

Давай уточним - ты утверждаешь, что сами выводимые диапазоны значения переменных являются implementation defined behavior?

Почитай вот это:

Strictly conforming programs are intended to be maximally portable among conforming implementations. Conforming programs can depend upon nonportable features of a conforming implementation.

И вот это:

A strictly conforming program shall use only those features of the language and library specified in this document. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.

Понимаешь, посыл? Программа не должна полагаться на то, что sizeof() вернет тебе 8. Но программа может вести себя одним образом если sizeof() возвращает 8 и другим, если он возвращает 4.

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

что сами выводимые диапазоны значения переменных являются implementation defined behavior?

Сами выводимые значения размеров, полученные через sizeof, являются результатом implementation defined behavior.

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

Но программа может вести себя одним образом если sizeof() возвращает 8 и другим, если он возвращает 4.

Если её вывод будет зависеть от этого, то она не strictly conforming program. Потому что суть strictly conforming program именно в том, что её вывод одинаков на всех компиляторах Си, соответствующих стандарту.

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

Сами выводимые значения размеров, полученные через sizeof, являются результатом implementation defined behavior.

М-м-м-м-м… Как сейчас будет вкусненько. Я тогда не только берусь доказать, что даже строго соответствующая Стандарту (strictly conforming) программа на Си может выдавать разные результаты в разных средах исполнения.

С таким допущением как твоё, я берусь утверждать, что строго соответствующая стандарту программа вообще не может ничего вывести. Единственный однозначно определённый тип данных в стандарте - это бит. Все остальные типы являются implementation defined:

5.2.4.2.1 Sizes of integer types <limits.h>

1
The values given below … Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

— number of bits for smallest object that is not a bit-field (byte)— minimum value for an object of type
CHAR_BIT8

И дальше для всех существующих в си типов. То есть буквально любой, существующий в си «встроенный» тип данных имеет implementation defined размерность.

В стандартной библиотеке си нет функций вывода единичных битов. Следовательно любой вывод в двоичном виде будет implementation defined, и программы строго соответсвующие стандарту ничего никуда выводить не должны. Даже return 0; в main имеет неизвестную битовую implementation defined разрядность.

И да, разумеется, всякие printf’ы сразу вылетают на свалку истории, потому что там ещё кодировки подскакивают кабанчиком.

С заявленным тобою уровнем формализма, ты вообще остался без языка программирования, с чем я тебя сердечно поздравляю!

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

Именно что строго. То, что ты обрабатываешь кейсы, как раз и делает ее строгой. Если бы ты полагался на то, что sizeof() всегда 8 и выдавал бы неверный результат — это как раз было бы нестрогое.

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

Если твоя платформа не позволяет выделить тебе терабайт памяти, твоя программа должна об этом сообщить и выйти. И, еще раз — нельзя полагаться на implementation defined. У тебя не должно быть ожиданий, что реализовано оно будет вот так вот, или что long int это всегда 8 байт. Но если это проверил благославленным способом, ты не внес нестрогость.

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

У тебя не должно быть ожиданий, что реализовано оно будет вот так вот, или что long int это всегда 8 байт. Но если это проверил благославленным способом, ты не внес нестрогость.

Внёс, так как результат программы становится зависимым от длины long int. В строго соответствующей ты должен в long int хранить в диапазоне -2147483647…2147483647, а не смотреть на sizeof.

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

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

Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign

Всё так. Эти значения использовать нельзя. Остальные можно.

Например, для int нельзя использовать значения больше 32767.

И дальше для всех существующих в си типов. То есть буквально любой, существующий в си «встроенный» тип данных имеет implementation defined размерность.

Именно поэтому значение sizeof является implementation defined.

В стандартной библиотеке си нет функций вывода единичных битов. Следовательно любой вывод в двоичном виде будет implementation defined

Да. Можно только в виде чисел в явно заданном формате.

Даже return 0; в main имеет неизвестную битовую implementation defined разрядность.

Нет. Здесь число возвращается как число, а не набор битов. В любом окружение это будет именно число 0, как бы в этом окружении 0 ни изображался.

И да, разумеется, всякие printf’ы сразу вылетают на свалку истории, потому что там ещё кодировки подскакивают кабанчиком.

printf как раз даёт одинаковый вывод на любой системе. Кодировка для char[] тоже не важна. Это уже трактовка вывода программы, а не её вывод.

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

Внёс, так как результат программы становится зависимым от длины long int. В строго соответствующей ты должен в long int хранить в диапазоне -2147483647…2147483647, а не смотреть на sizeof.

Ты выдираешь из контекста. Там же написано о чем речь: строго соответствующая программа должна полагаться только на описанные механизмы и использовать минимально допустимые значения, чтобы программа была портируемой. Если для реализации алгоритма тебе нужно знать размер sizeof… сделай это. Это описанный в стандарте механизм. Если программа будет работать на 16 битном процессоре читая все с диска, а на 64 битном процессоре делая все в памяти, это не делает её менее портируемой.

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

Если программа будет работать на 16 битном процессоре читая все с диска, а на 64 битном процессоре делая все в памяти, это не делает её менее портируемой.

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

В принципе, сейчас так memcpy в glibc выглядит. Пачка implementation defined веток с идентичным действием.

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

Да. Можно только в виде чисел в явно заданном формате.

Каком «явно заданном формате»? Где это в стандарте?

Нет. Здесь число возвращается как число, а не набор битов

Это абсурдное утверждение. Согласно стандарту любое число представлено как набор битов и любые операции происходят над ним. У тебя нет числа без набора битов. Набор битов даёт тебе какой-либо тип, в рамках которого ты можешь выразить число в некотором диапазоне. Любая операция над числом == операция над набором битов.

В любом окружение это будет именно число 0
Кодировка для char[] тоже не важна. Это уже трактовка вывода программы, а не её вывод.

Не-не-не, дэвид. Соскочить не получится. Ты сам заявил:

суть strictly conforming program именно в том, что её вывод одинаков на всех компиляторах Си, соответствующих стандарту.

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

Хочешь это опровергнуть - приведи формальное определение «вывода» программы из стандарта, подтверждающие твой тезис. Пока что твоя трактовка каких-то «чисел» в отрыве от бит натурально взята с потолка. Но у нас не лисп, у нас си.

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

для int нельзя использовать значения больше 32767

Найди доказательство этого тезиса в стандарте.

Подсказка - именно в этом месте в твоих рассуждениях логическая ошибка.

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

Единственный однозначно определённый тип данных в стандарте - это бит. Все остальные типы являются implementation defined

Для strictly conformant программ этого не требуется. В Annex E описаны минимальные размеры, ориентироваться нужно на них.

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

программа не удовлетворяет условию в твоём понимании

Хорошо. Предлагаешь какое-то другое понимание или просто хочешь доказать, что переносимых программ на Си не существует?

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

Согласно стандарту любое число представлено как набор битов и любые операции происходят над ним. У тебя нет числа без набора битов.

Только это представление зависит от реализации. А равенство вывода трактуется именно как равенство объектов языка (символов при вводе/выводе) и чисел при передаче через аргументы и результат.

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

Предлагаешь какое-то другое понимание

Я предлагаю однозначно определится с пониманием "It shall not produce output dependent " либо как двоично идентичным для любой «strictly conforming program», либо же однозначно признать, что вывод «strictly conforming program» может быть не идентичным.

Вот: and shall not exceed any minimum implementation limit

Тебе осталось сделать последний логический шаг - осознать это высказывание и термин «implementation limit», где слово «implementation» имеет решающее значение.

Коан в помощь для медитации - является ли strictly conforming следующая program:

#include <stdio.h>
#include <limits.h>

int main(void)
{
    (void) printf("%d\n", INT_MAX);
    return 0;
}
LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Коан в помощь для медитации - является ли strictly conforming следующая program:

Нет. Потому что надо читать весь термин, а не последние два слова. Minimum implementation limit описан в Стандарте и INT_MAX не может быть меньше, но, очевидно, может быть больше.

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

А равенство вывода трактуется именно как равенство объектов языка

Или докажи это текстом из стандарта, или тебе придётся отказаться от этого (выдуманного тобой) тезиса.

Нет.

Почему?

INT_MAX не может быть меньше, но, очевидно, может быть больше.

Да, может. А где тут какое-либо нарушение стандарта-то?

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

Или докажи это текстом из стандарта, или тебе придётся отказаться от этого (выдуманного тобой) тезиса.

В тексте вообще понятия равенства нет. Есть понятие зависимости. return 0; не зависит от «any unspecified, undefined, or implementation-defined behavior» и 0 не превышает «minimum implementation limit» для int.

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

Да, может. А где тут какое-либо нарушение стандарта-то?

Тут есть нарушение вот этого параграфа:

A strictly conforming program shall use only those features of the language and library specified in this document. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.

Minimum implementation limit для int это 16 бит (в Annex E). Если у тебя int 32 бит, ты превысил и твоя программа перестала быть strictly conforming.

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

В ту же степь с fopen: у тебя есть FOPEN_MAX, который объявлен stdio.h и чему-то равен. Однако, стандарт говорит что минимальное значение – 8. Если логика работы твоей программы подразумевает 12 открытых файлов, твоя программа уже не strictly conforming, даже если FOPEN_MAX на твоей платформе такое позволяет.

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

Тут есть нарушение вот этого параграфа:
shall not exceed any minimum implementation limit.
Minimum implementation limit для int это 16 бит (в Annex E).

Вернулся с каникул обратно в шкалку? Жаль, что учебный год начался с того, что ты обосрался не снимая штанов потому что не смог прочитать Annex E, на который ты же ссылаешься, где написано:

The minimum magnitudes shown shall be replaced by implementation-defined magnitudes with the same sign. … The components are described further in 5.2.4.2.1.

И именно implementation-defined magnitudes не должны быть exceed, а 5.2.4.2.1 говорит нам:

5.2.4.2.1 Sizes of integer types <limits.h>

The values given below shall be replaced by constant expressions … Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

Тебе пока рановато участвовать в таких срачах, лучше сделай домашку.

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

Вот тут ты близок

INT_MAX само по себе является результатом implementation-defined behavior.

Верно.

Поэтому его вывод не strictly conforming program.

Не верно. Помедитируй вот над этим коаном:

int main(void)
{
    int a = +32767;
    int b = a + 1;
    return 0;
}

Является ли эта программа strictly conforming?

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

The minimum magnitudes shown shall be replaced by implementation-defined magnitudes with the same sign

Эти значения являются minimum magnitudes. В программе они будут заменены implementation-defined magnitudes. Но эти implementation-defined magnitudes не становятся от этого minimum magnitudes. И там, где сравнение с minimum implementation limit сравнивается именно с minimum magnitudes, а не с implementation-defined magnitudes конкретной implementation.

P. S. Чем дальше, тем больше это напоминает философский спор с софистом. Надо отловить все попытки подмены смысла и явно их подчеркнуть.

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

Чем дальше, тем больше это напоминает философский спор с софистом

Со стороны это также выглядит. Вы тут ничего никому не докажите. Людям пофиг на истину, люди ищут самоутверждения.

Obezyan
()
Ответ на: комментарий от LamerOk

Ты не ту часть предложения выделил:

The minimum magnitudes shown shall be replaced by implementation-defined magnitudes

Видишь слово minimum? Ингриш, мазафака, да ю спик ит?

А то, что дальше цитируешь, отношение к strict conformity не имеет. Это про то что лимиты должны быть больше минимальных значений.

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

Ждем чего? Я тебе уже обосновал это формально – на 16 битной платформе у тебя signed overflow и это UB. В программе на языке C UB быть не может. Так что твоя программа не то что strictly conforming, она вообще не программа на языке C.

И прежде чем ты начнешь клоунаду в духе «ололо это значение даже не используется», то вот тебе простой пример UB, которое произойдет: твоя программа тупо не соберется с -Werror :DDD

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

Более того, я даже могу придумать реальный пример как это поделие сломается в реальной жизни. Потому что у нас есть программа, которая всегда возвращает 0… и это true!

А теперь давай посмотрим что будет, с поправкой на размер типа для x86_64:

$ cat true.c
int main(void)
{
    int a = +2147483647;
    int b = a + 1;
    return 0;
}
$ gcc -ftrapv -o true true.c
$ ./true
IOT instruction (core dumped)  ./true
$ echo $?
134

Ты все-таки умудрился написать программу, которая выдает разные значения на разных платформах, не делая буквально ничего. Браво, йопт. Это как самый маленький рассказ Хемингуэя, только от мира неспособных осилить сишный стандарт.

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

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

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

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

англюсика

Ловите тугосерю.

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

Тебе обязательно подтверждение от меня?

Подтверждение чего?

Тогда дождался.

Я жду логического объяснения причин, по которым ты отказал программе из поста в принадлежности к strictly conforming. Пока не вижу.

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

Я жду логического объяснения причин, по которым ты отказал программе из поста в принадлежности к strictly conforming. Пока не вижу.

Вы утомили уже своей тупостью и упрямством. Ваш пример не strictly conforming потому что:

A strictly conforming program shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior.

Signed overflow нарушает этот пункт. Поиск этих строчек в С стандарте оставляю вам как домашнее задание, хоть в стандарт загляните.

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

Вы утомили уже своей тупостью и упрямством. Ваш пример не strictly conforming потому что

Его поинт в том, что там нет вывода, поэтому на UB насрать. Но, как мы выяснили, вывод там есть :)))))))))

anonymous
()