LINUX.ORG.RU

Mergiraf — новый движок разрешения конфликтов в коде

 , , ,


2

5

Mergiraf – новый движок для git merge, учитывающий синтаксис языков программирования и позволяющий в автоматической режиме решать конфликты, например, в случаях, где изменения в одной строчке производятся над независимыми синтаксическими элементами или где порядок изменений не играет роли. Список поддерживаемых языков программирования и форматов данных весьма обширен. Для работы с исходным кодом используется библиотека Tree-sitter, что также позволяет легко добавлять поддержку новых языков при наличии парсера для TS.

Сам Mergiraf написан на языке Rust, исходный код опубликован на условиях GNU GPL 3.

>>> Документация по использованию

>>> Исходный код

★★★★★

Проверено: hobbit ()
Последнее исправление: unfo (всего исправлений: 6)
Ответ на: комментарий от Sm0ke85

В Сях слабая типизация: там можно double присвоить float'у и тебе за это ничего не будет, хотя может пострадать точность представления числа, например, что может быть критически важно. Вот в Паскале такого нет, там даже объявление синонима для типа потребует его явного приведения. И в Го такого нет: тебя обложит матом компилятор и не даст собрать программу. В Джаве такого тоже нет: нужно явно привести тип к нужному и пусть все видят какой ты дурак. Только ASM-подобный С позволяет тебе выстрелить себе в ногу на поле типизации.

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

То-то в ffmpeg удивятся, что асмом нельзя пользоваться.

По рукам! Пусть тот, кто делает коммиты с ассемблерными вставками, покажет сначала свой вклад в сердце ffmpeg.

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

В Сях слабая типизация: там можно double присвоить float’у и тебе за это ничего не будет, хотя может пострадать точность представления числа, например, что может быть критически важно. Вот в Паскале такого нет, там даже объявление синонима для типа потребует его явного приведения. И в Го такого нет: тебя обложит матом компилятор и не даст собрать программу. В Джаве такого тоже нет: нужно явно привести тип к нужному и пусть все видят какой ты дурак. Только ASM-подобный С позволяет тебе выстрелить себе в ногу на поле типизации.

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

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

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

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

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

Ты опять нафантазировал, алеша, тебе ж потом пояснили, что имелась ввиду корректность в терминах языка, а вот диссонанс в некорректности «работы» программы как раз был предметом обсуждения…

Ты, конечно же, как всегда неправ, потому что ты не знаешь языка Си. В языке Си некорректная программа вполне может откомпилироваться (даже без ошибок) и запуститься. Смотри в сторону такого мерзкого феномена как Undefined Behaviour. Например, следующий кусок кода некорректен, но отлично собирается.

void f(struct s *foo) {
  int x = foo->x;
  
  if(s == NULL)
    return;
  printf("%d\n", x);
}

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

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

Ты, конечно же, как всегда неправ, потому что ты не знаешь языка Си. В языке Си некорректная программа вполне может откомпилироваться (даже без ошибок) и запуститься. Смотри в сторону такого мерзкого феномена как Undefined Behaviour. Например, следующий кусок кода некорректен, но отлично собирается.

не компилируется, да и не должно собственно, т.к. ты кусок от типа проверяешь на NULL… Получается я прав…

Это единственная ошибка во всем коде (собственно, ее сразу видно), т.к. есть тип «struct s» и есть ссылка на структуру «foo»

1.c:11:6: ошибка: «s» не описан (первое использование в этой функции) 11 | if(s == NULL)

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

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

Как я и говорил, ты балабол и неуч, опять лужу вспенил)))…

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

Это единственная ошибка во всем коде (собственно, ее сразу видно), т.к. есть тип «struct s» и есть ссылка на структуру «foo»

Сорри, опечатался, писал с телефона %)

#include <stdio.h>
#include <stdlib.h>

struct s {
  int x;
};

void f(struct s *foo) {
  int x = foo->x;
  
  if(foo == NULL)
    return;
  printf("%d\n", x);
}

int main(void) {
  struct s *p = calloc(1, sizeof(*p));
  f(p);
}

Ты понимаешь стандарт так, как тебе выгодно сиюминутно

Это-то ладно. Важно то, как его понимают разработчики компиляторов. Вот там реально мрак!

ты так и не представил ни одного куска кода на Си, написанного тобой, чтоб он подтвердил твои слова…

Вот же выше. Код компилируется с -Wall -Wextra -Werror и при этом содержит ошибку с точки зрения языка. Магия!

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

Вот же выше. Код компилируется с -Wall -Wextra -Werror и при этом содержит ошибку с точки зрения языка. Магия!

Не вижу ошибки в коде, да и программа работает (gcc, clang), даже флаги О3 попробовал, короче этот код рабочий, к нему претензий у меня не возникает (попроверял даже с заполненной структурой), кроме отсутствия ретурна 0.

#include <stdio.h> #include <stdlib.h>

struct s { int x; };

void f(struct s *foo) { int x = foo->x;

if(foo == NULL) return; printf(«%d\n», x); }

int main(void) {

struct s *p = calloc(1, sizeof(*p));

p->x = 5; printf («%d\n»,p->x);

f(p); }

Не сгенерил ты ошибку про которую рассказал… PS напрягает только отсутствие «return 0;», но там и без всей этой магии компилируется и работает без ретурна, хотя были времена, когда компиляторы ругались, если я правильно помню…

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

Я увидел таки ошибку, и да косяк конечно (сразу глаз не зацепился), но тут не сам Си виновен, а программа некорректная, т.к. проверка на NULL происходит уже после использования указателя, это Си тут стоит «понять и простить», все на программисте.

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

PS но к истории с volatile это не относится, т.к. тут очевидно поведение кривое будет, в отличии допустим от ситуации где у тебя из-за отсутствия волатайла и жестких оптимизаций превратился цикл из одной строки в цикл по 4 одинаковых строки с предрассчитанными коэффициентами допустим…

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

Я увидел таки ошибку, и да косяк конечно (сразу глаз не зацепился), но тут не сам Си виновен, а программа некорректная, т.к. проверка на NULL происходит уже после использования указателя, это Си тут стоит «понять и простить», все на программисте.

Почему? Кто мешает в Си сделать гарантированно ненулевые указатели?

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

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

но к истории с volatile это не относится, т.к. тут очевидно поведение кривое будет

Или не кривое. Или не будет. Оба случае – пример UB.

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

Почему? Кто мешает в Си сделать гарантированно ненулевые указатели?

Железо мешает и необходимость иметь не сложный компилятор - очевидно же…

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

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

Или не кривое. Или не будет. Оба случае – пример UB.

Разница огромная в этих ситуациях, в твоем примере заложена проблема на уровне Си кода, в случаи с волатайлом логику твоей программы, по сути, ломает компилятор (в зависимости от флагов компиляции, например), из-за чего может получиться, что у тебя твоя одна и та же переменная используется из двух разных мест (например, кэш камня и память)…

Также в твоем примере проблема изначально после компиляции заложена, а в случае с volatile она может появляться/исчезать от компиляции к компиляции, а это принципиальная разница (т.е. ты можешь скомпилировать и все будет при любых тестах работать исправно, но после следующей компилиции ты сразу попадаешь на неправильное поведение, отсюда и мое слово «полечить проблему», по моему мнению volatile - это костыль и не более)…

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

По мне так пусть git автоматически делает только примитивные слияния. Для остального есть mergetool в виде kdiff3 или sublime merge.

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

По мне так пусть git автоматически делает только примитивные слияния. Для остального есть mergetool в виде kdiff3 или sublime merge.

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

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

Железо мешает и необходимость иметь не сложный компилятор - очевидно же…

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

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

undefined behavior

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

Грубо говоря, для случаев, когда в функцию прилетает NULL, компилятор волен сгенерировать любое говно вместо кода. Например, выкинуть проверку.

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

Какую именно логику? С точки зрения языка, описанного в стандарте, компилятор ничего не ломает. Повторю цитату:

herefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3.

Доступ к обычным переменным не является побочным эффектом (side effect) с точки зрения абстрактной машины языка Си. Доступ к volatile переменным является. Пункт 5.1.2.3:

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,12) which are changes in the state of the execution environment

Компилятор Си гарантирует, что корректная программа (т.е. без UB) будет выполнять побочные эффекты в том порядке, в котором они описаны. Изменения же внутреннего состояния программы могут меняться порядком из-за оптимизаций. Хуже того…

In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced

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

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

Оно является неправильным, это твоя программа неправильная. Потому что…

отсюда и мое слово «полечить проблему», по моему мнению volatile - это костыль и не более

… ты не знаешь языка, на котором пытаешься писать.

TL;DR: программа на языке Си модифицирует некое внешнее состояние (execution environment) относительно некоей абстрактной машины, описанной в стандарте (он правда довольно херово написан, если честно). Модификациями внешнего состояния (execution environment) являются: работа с файлами, сокетами, любыми другими внешними объектами, а также работа с volatile объектами. Порядок таких модификаций гарантируется стандартом (при условии отсутствия UB в программе). Порядок же любых других вычислений не гарантируется никак и никем и может быть любым. Вбей это себе в голову и перестань писать тут полную хероту.

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

Грубо говоря, для случаев, когда в функцию прилетает NULL, компилятор волен сгенерировать любое говно вместо кода. Например, выкинуть проверку.

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

Какую именно логику? С точки зрения языка, описанного в стандарте, компилятор ничего не ломает. Повторю цитату:

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

Оно является неправильным, это твоя программа неправильная. Потому что…

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

… ты не знаешь языка, на котором пытаешься писать.

Ты опять лужу решил вспенить..? Сколько клонадить будешь…?

TL;DR: программа на языке Си модифицирует некое внешнее состояние (execution environment) относительно некоей абстрактной машины, описанной в стандарте (он правда довольно херово написан, если честно). Модификациями внешнего состояния (execution environment) являются: работа с файлами, сокетами, любыми другими внешними объектами, а также работа с volatile объектами. Порядок таких модификаций гарантируется стандартом (при условии отсутствия UB в программе). Порядок же любых других вычислений не гарантируется никак и никем и может быть любым. Вбей это себе в голову и перестань писать тут полную хероту.

Вот тут то у тебя и беда, я ж говорю ты в Си не пишешь… Друг, а что если нет сокетов, нет абстрактных машин и объектов нет, ничего нет кроме железа…? Ты НЕ пишешь под железо, ты просто читатель стандарта, это прикольно, можешь хелло ворлд написать или приложеньице в командную строку и это все… Я работаю не в абстрактной машиной, не с объектами и не с сокетами, я сам пишу и описываю поведение железа, функции вывода и интерфейсы связи, поэтому и говорю, что ты в Си ничерта не умеешь, у тебя язык закончился на абстракции и стандарте, ты под капот ему не лазаешь, многие проблемы не знаешь даже, т.к. для тебя Си - это gcc, clang, g++ и что там в стандарте написали…

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

Грубо говоря, для случаев, когда в функцию прилетает NULL, компилятор волен сгенерировать любое говно вместо кода. Например, выкинуть проверку.

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

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

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

Кто не рекомендует? Голоса в твоей голове?

по твоей логике можно все глобальные переменные укатать в волатайлы смело

Нет, это не моя логика. Я не знаю, откуда ты взял эту идею. В volatile нужно укатать те объекты, порядок доступа к которым имеет значение и может наблюдаться извне. Под «извне» подразумевается не только снаружи программы (например, как в случае с разделяемой памятью), но и из других тредов и контекстов, в т.ч. из обработчиков прерываний и сигналов.

Ты опять лужу решил вспенить..? Сколько клонадить будешь…?

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

Друг, а что если нет сокетов, нет абстрактных машин и объектов нет, ничего нет кроме железа…?

Имеется ввиду абстрактная машина языка, а не виртуалка. Под объектами имеются ввиду объекты языка, а не объекты из ООП.

у тебя язык закончился на абстракции и стандарте, ты под капот ему не лазаешь, многие проблемы не знаешь даже, т.к. для тебя Си - это gcc, clang, g++ и что там в стандарте написали…

Это не для меня. Это для авторов компиляторов язык – то, что в стандарте написали. Если реализация языка не соответствует стандарту, то это реализация какого-то другого языка, а не Си.

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

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

Или слабо было потому что дернул откуда-то код…?

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

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

Мне платят построчно.

а ты огород нагородил, который особо не к чему…

Как ты программируешь, если ты «не» с «ни» путаешь?

Или слабо было потому что дернул откуда-то код…?

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

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

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

Там ошибка зашита в логику, а при volatile у тебя после компиляции (даже в зависимости от архитектур) может скомпилироваться либо РАБОЧАЯ программа, либо НЕРАБОЧАЯ - чувствуешь разницу…?

Кто не рекомендует? Голоса в твоей голове?

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

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

Не фантазируй, все что ты привел из стандарта, это описание volatile и с ним я не спорю, проблема в том что пересказывая стандарт ты излишне нафантазировал…

Имеется ввиду абстрактная машина языка, а не виртуалка. Под объектами имеются ввиду объекты языка, а не объекты из ООП.

Мне от этого ни горячо не холодно, т.к. код компилируется под Реальные машины и проблемы (и в том числе причины этих проблем) Реальные, и если ты в вакууме на абстрактной машине (одной, полностью описанной) можешь точно определить необходимость проставления volatile, то на зоопарке реальных архитектур вспенишь лужу…

И вот тебе вопрос: Может ли повлиять степень оптимизации на необходимость применения volitile?

Это не для меня. Это для авторов компиляторов язык – то, что в стандарте написали. Если реализация языка не соответствует стандарту, то это реализация какого-то другого языка, а не Си.

Вот это корень раздора и есть, считаю. Ты язык Си воспринимаешь как стандарт, а я как инструмент…

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

Мне платят построчно.

Жди сокращение тогда, ИИ агенты не дремлют…

Как ты программируешь, если ты «не» с «ни» путаешь?

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

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

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

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

Там ошибка зашита в логику

Не совсем. Из-за UB, компилятор вполне может превратить первый кусок кода ниже во второй. Это будет корректным преобразованием:

int deref1(int *p) {
  int x = *p;
  if(p == NULL)
    return 0;
  else
    return x;
}
int deref2(int *p) {
  if(p == NULL)
    return 0;
  else
    return *p;
}

а при volatile у тебя после компиляции (даже в зависимости от архитектур) может скомпилироваться либо РАБОЧАЯ программа, либо НЕРАБОЧАЯ - чувствуешь разницу…?

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

Не фантазируй, все что ты привел из стандарта, это описание volatile и с ним я не спорю, проблема в том что пересказывая стандарт ты излишне нафантазировал…

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

Мне от этого ни горячо не холодно, т.к. код компилируется под Реальные машины

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

Вот это корень раздора и есть, считаю. Ты язык Си воспринимаешь как стандарт, а я как инструмент…

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

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

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

А в чём разница между ними?

На деле, компилятор видит разыменование, делает вывод, что условие всегда false, и может оптимизировать до:

int deref2(int *p) {
  return *p;
}
unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

А в чём разница между ними?

В наличие NULL pointer deference :)

Впрочем, главный лулз в том, что никто тебе не мешает разместить по адресу 0 вполне валидные данные. Даже в линуксе, да, ты вполне можешь замапить страницу по нулевому адресу и срать туда сколько влезет, но компилятор тебе всячески будет мешать писать такой код. Идея сделать вполне валидный адрес невалидным значением и нахерачить особых правил вокруг него вообще очень тупая. Как и многие другие идеи, заложенные в язык Си.

На деле, компилятор видит разыменование, делает вывод, что условие всегда false, и может оптимизировать до:

На деле, компилятор может выдать вообще что угодно. UB на то и UB, что требований на поведение выданного кода нет никаких.

Но да, твой пример тоже корректен.

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

В наличие NULL pointer deference :)

В каком месте?

На деле, компилятор может выдать вообще что угодно

Ээээ, не. Сама по себе эта функция не содержит UB, если мы не передаём в неё NULL.

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

Зачем сделана эта оптимизация - для выкидывания лишнего кода при раскрытии макросов и инлайнинге. Как пример, пусть у нас есть две функции:

int deref(int *p) {
  if (p == NULL) {
    return 0;
  }

  return *p;
}

void do_stuff(int *p) {
  some_function(*p);

  another_function(deref(p));
}

Компилятор вправе выкинуть проверку на NULL из функции deref(), если он решил её заинлайнить или может доказать, что она больше ниоткуда не вызывается. Может выкинуть, потому что если бы указатель был NULL, то было бы UB в функции do_stuff. Исходя из того что в программах UB не бывает, делается вывод, что условие никогда не выполняется, и проверку можно выкинуть нафиг.

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

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

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

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

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

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

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

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

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

Да эмбедщики многие такие ушибленные. Они же написали программу для контроллера, у которого памяти 100 байт, и даже отладили её всего за три недели, это крутое достижение. Компилировать нужно такой версией компилятора с такими вот флагами, и тогда она даже будет работать.

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

Не совсем. Из-за UB, компилятор вполне может превратить первый кусок кода ниже во второй. Это будет корректным преобразованием:

Такое преобразование исключено

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

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

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

А я прочитал и чудно для тебя, но со стандартом не спорю…

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

Согласно да ни согласно стандарту, т.к. налагает отпечаток зоопарк архитектур, поэтому есть абстракция, а есть реализация, между ними пропасть…

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

Да кто ж тебе сказал что стандартом пользоваться некамильфо…? Ты в Си не умеешь - это факт, особенно после слов, что тебе платят за строчки (на примере твоего же кода), ибо тот кто на Си действительно пишет, тот на подкорке не будет лишние абстракции и вызовы функций делать, дабы сэкономить ресурсы, сохранить быстродействие, уменьшить размер исполняемого файла… Хорош короче рассказывать… И в твоем же последнем коде-примере, так оптимизации не сработают, потому что ты слабо представляешь во что это превратиться в машинных кодах и как это ляжет на архитектуру…

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

Мда уж, я как раз после армейки планировал выходить из embedded (скучно там), а с такими персонажами вообще страшно – они же потенциальные коллеги!

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

Да эмбедщики многие такие ушибленные.

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

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

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

const, extern и static тоже выкинем из программы?

u-235
()
Ответ на: комментарий от u-235

const, extern и static тоже выкинем из программы?

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

PS на всякий случай озвучу для «фантазеров»: я не имею ничего против использования данных модификаторов и сам их с удовольствием использую.

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

Такое преобразование исключено

Кем исключено? У меня другая информация.

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

Любой код – просто указание компилятору. Тем не менее, volatile, const и так далее вполне влияют на выполнение кода.

Согласно да ни согласно стандарту, т.к. налагает отпечаток зоопарк архитектур, поэтому есть абстракция, а есть реализация, между ними пропасть…

Какой именно отпечаток налагает? Объясни. Мы почитаем, любопытно жеж!

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

Кем исключено? У меня другая информация.

Теперь вижу, ибо присутствует флаг O2.

Любой код – просто указание компилятору. Тем не менее, volatile, const и так далее вполне влияют на выполнение кода.

Это не верно в корне, и ты сам это знаешь.

Какой именно отпечаток налагает? Объясни. Мы почитаем, любопытно жеж!

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

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

Пока я не вижу, для чего бы мне Раст. Если вдруг мне придется реализовывать формально верифицированные модели, то буду использовать те языки, в которые генерится модель. Знаю, что какой-нибудь event-B умеет в Аду. Если Раст когда-нибудь обретет хотя бы что-то типа ACSL, то, может быть и он сгодится.

А от растаманов точно хочется держаться подальше. Не нравится мне это их «старый мир разрушим» (с) и нездоровый блеск в глазах.

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

Кем исключено? У меня другая информация.

Теперь вижу, ибо присутствует флаг O2.

Молодец! У нас прогресс!

Любой код – просто указание компилятору. Тем не менее, volatile, const и так далее вполне влияют на выполнение кода.

Это не верно в корне, и ты сам это знаешь.

Это верно, и я сам это знаю, потому что я это написал.

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

Нет, volatile не запрещает оптимизировать. Volatile переводит обращение к объекту в разряд наблюдаемых побочных эффектов. Да, это сужает класс применимых оптимизаций – в частности, модификацию таких объектов нельзя выкинуть – но не исключает их полностью.

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

Молодец! У нас прогресс!

Интересный ты я посмотрю, так с флагом -O0 или без флага попробуй и все встанет у тебя на места, а то я смотрю ты сам-то в вакууме да еще и в Цпп почему-то сишный код рассматриваешь (кстати, опять в Срр пробуешь, а речь ведешь за С), а тут удосужился показать таки мысли свои… Конечно прогресс, я тебе про это и пишу постоянно…

Это верно, и я сам это знаю, потому что я это написал.

Я намекну, что есть еще дериктивы препроцессора, да и флаги компиляции получается на большинство твоих «указаний» плевать хотели. Ты ж посмотри без флагов во что код превращается в асме и действительно поуказывай например volatile’ом и увидишь разницу… Да и «6.7.4 Type qualifiers» из стандарта намекает, что это что-то отдельное…

Нет, volatile не запрещает оптимизировать. Volatile переводит обращение к объекту в разряд наблюдаемых побочных эффектов. Да, это сужает класс применимых оптимизаций – в частности, модификацию таких объектов нельзя выкинуть – но не исключает их полностью.

На:

An object that has volatile-qualified type may be modified in ways unknown to the implementation
or have other unknown side effects. Therefore, any expression referring to such an object shall be
evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.4. Furthermore,
at every sequence point the value last stored in the object shall agree with that prescribed by the
abstract machine, except as modified by the unknown factors mentioned previously.150) What
constitutes an access to an object that has volatile-qualified type is implementation-defined.

A volatile declaration can be used to describe an object corresponding to a memory-mapped input/output port or an object accessed by an asynchronously interrupting function. Actions on objects so declared are not allowed to be "optimized out" by an implementation or reordered except as permitted by the rules for evaluating expressions.
Sm0ke85
()
Ответ на: комментарий от Sm0ke85

так с флагом -O0 или без флага попробуй и все встанет у тебя на места

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

Да и «6.7.4 Type qualifiers» из стандарта намекает, что это что-то отдельное…

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

На:

Ага. Я тебе эту цитату выше уже кидал, а ты плевался и про «the rules of the abstract machine» писал, что нет никакой абстрактной машины, а только железо. Мне кажется, ты приближаешься к TOP 5 моих любимых ЛОРовских шизофреников.

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

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

Я верно понял, что ты так и не понял что в том куске стандарта написано?

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

Отчего ж ты по написанному прочитать не можешь тогда? Опять включил режим «фантазер-зер-зер»)))) Ты вон выше опять нафантазировал, что для тебя одного порядка printf и volitile, и делаешь вид, что все Ок, привеД Наполеону передай в следущую вашу встречу по захвату земли Шумерской, ахахах)))…

Ага. Я тебе эту цитату выше уже кидал, а ты плевался и про «the rules of the abstract machine» писал, что нет никакой абстрактной машины, а только железо. Мне кажется, ты приближаешься к TOP 5 моих любимых ЛОРовских шизофреников.

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

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

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

понять не можешь, там черным по белому написано

Ну перескажи своими словами, как ты понимаешь этот стандарт. А то с твоих слов пока что получается, что стандарт пишет «в случае ошибок ставь volatile там-сям и гоняй программу, пока не начнёт выдавать что-то похожее на правду».

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

Я верно понял, что ты так и не понял что в том куске стандарта написано?

Нет. Хуже того, ты сам не понял, что там написано.

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

Видимо, редко решаешь конфликты.

К несчастью, нет. Причём в команде именно слияниями в основном я занимаюсь.

конфликты тривиальные

У kdiff3 я не припомню, что бы совсем уж тривиальные конфликты оставались, обычно где и головой подумать уже нужно было, а иногда и поправить результат. Были даже случаи: git отвалился, а kdiff3 почти всё переварил нормальным образом сразу на запуске. Просто бегло посмотреть оставалось и подтвердить.

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

hatred ★★★
()

@Tinker

Кривые компиляторы, вот почему. В коде имеется side-effect - генерация NPE, но оптимизатор его выкинул.

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

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

P.S. пришёл @hobbit и снёс половину ветки. Ну вот нахера? У тебя зачесалось прямо так сильно?

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

Rust сложнее Си, причем на много

Точно?? Это ваш личный опыт? А то тут, в соседней теме, меня пара явных «растаманов» агитируют, что, мол, «на С больше низ-зя! Надо на Rust!»... :)) А мне для микроконтроллеров писать надо...

Ваше мнение? Как быть?.. :))

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

тут, в соседней теме, меня пара явных «растаманов» агитируют, что, мол, «на С больше низ-зя! Надо на Rust!»… :)) А мне для микроконтроллеров писать надо…

Ваше мнение? Как быть?.. :))

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

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

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

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

Как-то проповеди «Свидетелей Иеговы» напомнило... :))

Мне бы попроще... Шоб поменьше вот этих всех е-моций, да поближе «к земле»... к «железу» в смысле... :)

P.S. На С я уже писал... Ничего, выжил... не превратился... :))

Somebody ★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.