На вход итераторы, а на выход — поинтер… Слов нет, одни выражения. А, ну и голый эррор код. С++ так и не смог нормальную единую обработку ошибок, сплошные костыли.
Рейсер сам по себе уже давно не разрабатывается.
Для VSCode — RLS и соответственно поставить RLS как компонент. Единственная проблема — пока что для этого надо ставить найтли тулчейн. Сижу и пишу частично под виндовс, проблем в целом не имею.
Уважаемый antoshkka, у вас случайно нет "человекочитаемого" описания текущего состояния по модулям — на каком уровне они существуют (грубо — единица трансляции или линковки), как предполагается существующий код с инклюдами приводить к модульному виду и т.п. Судя по https://habrahabr.ru/company/yandex/blog/336264/#comment_10449246, понимания, как оно должно быть, нет как минимум у меня.
Проблема ЕМНИП в том, что как только вы измеряете состояние одной частицы из пары, и получаете какой-то параметр для обоих, запутанность "сыпется", и у вас на руках 2 отдельных частицы. Поэтому данное явление на данный момент считается неприменимым для передачи информации быстрее скорости света. Более знающие да поправят.
Следствием второго принципа (и общенаучного принципа причинности) является невозможность движения физических тел и передачи информации со скоростью, превышающей скорость света в вакууме.
Так что квантовая запутанность "передаётся" мгновенно — но передать этим способом информацию нельзя.
Тогда я не понимаю, какой уровень призваны организовать модули. Если уровень юнитов трансляции — то где, действительно, возможность организовать приватные детали реализации, и зачем такие с мультифайловостью и отдельным именованием? Если же уровень единиц сборки — зачем отдельно декларировать везде имя модуля, и что будет, если несколько модулей лягут в один бинарь?
Да, придётся добавить к таким функциям export. Зато будет понятно, где что лежит. При описанном вами сценарии с модулем в 10К строчек, делённым на несколько файлов, придётся ещё выяснять где лежит каждый кусок — т.к. логическое имя модуля вообще никак не связано с его местоположением в исходниках.
Пример с обработкой ошибок просто самый наглядный. Во второй половине комментария описан чуть более сложный случай. Добавьте туда пункт 2.5:
Функции, возвращающие инстансы конкретных типов, используются в других местах модуля для получения этих инстансов, но без необходимости приводить указатели к единому интерфейсу.
Проблема именно в том, что в сколь-нибудь нетривиальном коде вполне можно получить "битый интерфейс" на ровном месте.
// Note: both FirstError and SecondError implement 'error' interface
// and use some data from value when their respective Error() is called
// May return non-nil error, if code fails
func first(arg MyData) *FirstError { /* some code here */ }
// May also return non-nil error, if code fails
func second(arg MyData) *SecondError { /* some other code here */ }
func third(arg MyHugeData) error {
if err := first(arg.DataField); err != nil {
return err
}
return second(arg.DataField)
}
func fourth(arg MyHugeData) {
if err := third(arg); err != nil {
fmt.Println(err.Error())
}
}
Такой код КМК вполне может случиться — "просто верни статус последней операции дальше по стеку". Во-первых, результат всегда будет трактоваться как неуспех. Во-вторых, при попытке узнать причину мы получим nil-pointer panic из по сути ниоткуда. Пример с обработкой ошибок КМК просто будет самый типичный. Я в своё время нарвался на такое поведение в другом контексте, подробностей уже не помню.
Но суть была именно такой:
Есть несколько типов, приводимых к одному интерфейсу.
Каждый из типов требует не-нулевой инстанс чтобы корректно реализовывать указанный интерфейс
В некоем коде, допустим при передаче через канал, указатель на объект какого-либо из конкретных типов приводится к интерфейсу. При этом для канала nil pointer является абсолютно корректным положением вещей и обрабатывается на принимающей стороне как положено.
На принимающей стороне не-нулевой указатель на интерфейс неожиданно оказывается очень даже нулевым, т.к. сам по себе vtable бесполезен. Результат — NPE где не ждали.
Мне в общем-то тоже понятно, почему так происходит. Мне даже понятно, для чего используется эта фича. Что мне, к сожалению, осталось непонятно — почему это разрешено в виде неявного преобразования. Как по мне, сильно повышает шансы наступить на грабли. Было бы в виде явного тайп каста, так что неявный приводит к fully nil interface pointer — вопросов бы не было. Впрочем, как реализовали так реализовали. Может в v2 поменяют. Или давно есть линт, о котором я не знаю.
Подскажите пожалуйста одну вещь. В своё время я задавал вопрос, почему существует такая вещь как not-so-nil interface pointers — ситуация, когда nil-указатель на переменную конкретного типа неявно приводится к указателю на интерфейс, который этот тип реализует. И, как результат, у нас получается fat pointer с nil data pointer и валидным vtable pointer. Следствие — nil pointer dereference в рантайме, где его не ждали. Но вопрос не в этом. Вопрос в том, что ответ тогда был "потому что в Go указатели, а не ссылки". Как раз этот ответ я и не понял.
Вместо того, чтобы сделать простой и понятный импорт по относительным путям
// <root>/src/Module1.cpp
import "Dir1/Module2"; // See below
// some code goes here
// ...
// <root>/src/Dir1/Module2.cpp
import "std/vector";
// some code with exports goes here
Это КМК решило бы сразу несколько проблем — не нужно явно указывать имя модуля, пути импорта понятны из кода, плюс естественная возможность приватных модулей. Если вы скажете "а как же многофайловые модули?" — а зачем они вообще нужны? Откровенно выглядит как костыль. Генерацию интерфейсной части из общего текста модуля можно как раз оставить на совести компилятора.
Глобальный модуль
В черновике упомянут некий "глобальный модуль", в который входит весь код до декларации module. Этот двойной пассаж мне честно говоря не понятен. Единственное подозрение — необходимость куда-то деть содержимое файла до декларации модуля.
Хм, в таком случае извиняюсь. К вам в профиль не заглядывал. Да и вроде как не троллил, пытался просто пообсуждать. Впрочем, всего доброго, эта ветка явно изжила себя.
К сожалению, вы не совсем понимаете мой вопрос. Я упоминаю defer только как механизм для гарантированного закрытия, не более. Я не говорю, что он обязателен для чего-либо. Мой вопрос хотя бы о минимальной ситуации, когда переменная, содержащая неуправляемый ресурс, была создана (не передана снаружи) внутри функции, не "ушла наружу" и при этом не была корректно закрыта. По моему опыту, такая ситуация довольно часто встречается в реальном коде.
Чтобы проигнорить ошибку, вам придется сознательно написать вместо err — _ что означает "я сознательно игнорирую это значение, потому что так надо".
Окей, тут согласен. Давно не писал, возможно так и было. Впрочем, вопрос boilerplate остаётся, хоть и не так остро.
И чем при выходе из скопа не устраивают defer тогда?
Всем устраивает. Кроме того, что последний раз, когда я имел дело с Go, компилятор никак не предупреждал, что я его пропустил. Или ситуация поменялась, и я напрасно ною?
Меня больше бомбануло от
На вход итераторы, а на выход — поинтер… Слов нет, одни выражения. А, ну и голый эррор код. С++ так и не смог нормальную единую обработку ошибок, сплошные костыли.
Рейсер сам по себе уже давно не разрабатывается.
Для VSCode — RLS и соответственно поставить RLS как компонент. Единственная проблема — пока что для этого надо ставить найтли тулчейн. Сижу и пишу частично под виндовс, проблем в целом не имею.
Любопытно, спасибо. Вопрос в том, как сделать такое "слабое квантовое измерение". Посмотрим.
Если совсем коротко — линкуетесь с Qt динамически (фреймворк в отдельных DLL/SO) и творите что хотите. В своём коде конечно.
Уважаемый antoshkka, у вас случайно нет "человекочитаемого" описания текущего состояния по модулям — на каком уровне они существуют (грубо — единица трансляции или линковки), как предполагается существующий код с инклюдами приводить к модульному виду и т.п. Судя по https://habrahabr.ru/company/yandex/blog/336264/#comment_10449246, понимания, как оно должно быть, нет как минимум у меня.
Подозреваю, что этот и предыдущий комментарий — ответы на https://habrahabr.ru/company/technoserv/blog/339156/#comment_10449494
Проблема ЕМНИП в том, что как только вы измеряете состояние одной частицы из пары, и получаете какой-то параметр для обоих, запутанность "сыпется", и у вас на руках 2 отдельных частицы. Поэтому данное явление на данный момент считается неприменимым для передачи информации быстрее скорости света. Более знающие да поправят.
Скорость света — предельная скорость передачи любого взаимодействия, не только движения.
https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8#.D0.A1.D0.BF.D0.B5.D1.86.D0.B8.D0.B0.D0.BB.D1.8C.D0.BD.D0.B0.D1.8F_.D1.82.D0.B5.D0.BE.D1.80.D0.B8.D1.8F_.D0.BE.D1.82.D0.BD.D0.BE.D1.81.D0.B8.D1.82.D0.B5.D0.BB.D1.8C.D0.BD.D0.BE.D1.81.D1.82.D0.B8
Предпоследний абзац
Так что квантовая запутанность "передаётся" мгновенно — но передать этим способом информацию нельзя.
Тогда я не понимаю, какой уровень призваны организовать модули. Если уровень юнитов трансляции — то где, действительно, возможность организовать приватные детали реализации, и зачем такие с мультифайловостью и отдельным именованием? Если же уровень единиц сборки — зачем отдельно декларировать везде имя модуля, и что будет, если несколько модулей лягут в один бинарь?
Да, придётся добавить к таким функциям export. Зато будет понятно, где что лежит. При описанном вами сценарии с модулем в 10К строчек, делённым на несколько файлов, придётся ещё выяснять где лежит каждый кусок — т.к. логическое имя модуля вообще никак не связано с его местоположением в исходниках.
Пример с обработкой ошибок просто самый наглядный. Во второй половине комментария описан чуть более сложный случай. Добавьте туда пункт 2.5:
Функции, возвращающие инстансы конкретных типов, используются в других местах модуля для получения этих инстансов, но без необходимости приводить указатели к единому интерфейсу.
Проблема именно в том, что в сколь-нибудь нетривиальном коде вполне можно получить "битый интерфейс" на ровном месте.
Эмм, просто поделить на несколько вложенных модулей? С указанным подходом это будет тривиально.
Вырожденный пример будет какой-то такой
Такой код КМК вполне может случиться — "просто верни статус последней операции дальше по стеку". Во-первых, результат всегда будет трактоваться как неуспех. Во-вторых, при попытке узнать причину мы получим nil-pointer panic из по сути ниоткуда. Пример с обработкой ошибок КМК просто будет самый типичный. Я в своё время нарвался на такое поведение в другом контексте, подробностей уже не помню.
Но суть была именно такой:
Мне в общем-то тоже понятно, почему так происходит. Мне даже понятно, для чего используется эта фича. Что мне, к сожалению, осталось непонятно — почему это разрешено в виде неявного преобразования. Как по мне, сильно повышает шансы наступить на грабли. Было бы в виде явного тайп каста, так что неявный приводит к fully nil interface pointer — вопросов бы не было. Впрочем, как реализовали так реализовали. Может в v2 поменяют. Или давно есть линт, о котором я не знаю.
Подскажите пожалуйста одну вещь. В своё время я задавал вопрос, почему существует такая вещь как
not-so-nil interface pointers— ситуация, когда nil-указатель на переменную конкретного типа неявно приводится к указателю на интерфейс, который этот тип реализует. И, как результат, у нас получается fat pointer с nil data pointer и валидным vtable pointer. Следствие — nil pointer dereference в рантайме, где его не ждали. Но вопрос не в этом. Вопрос в том, что ответ тогда был "потому что в Go указатели, а не ссылки". Как раз этот ответ я и не понял.Подскажите пожалуйста кто в курсе по поводу двух особенностей модулей:
Своя нотация именования
Вместо того, чтобы сделать простой и понятный импорт по относительным путям
Это КМК решило бы сразу несколько проблем — не нужно явно указывать имя модуля, пути импорта понятны из кода, плюс естественная возможность приватных модулей. Если вы скажете "а как же многофайловые модули?" — а зачем они вообще нужны? Откровенно выглядит как костыль. Генерацию интерфейсной части из общего текста модуля можно как раз оставить на совести компилятора.
Глобальный модуль
В черновике упомянут некий "глобальный модуль", в который входит весь код до декларации
module. Этот двойной пассаж мне честно говоря не понятен. Единственное подозрение — необходимость куда-то деть содержимое файла до декларации модуля.Я попытался спросить в общей гугл группе https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/SdgWgJCR35s, но мне к сожалению так никто и не ответил.
Хм, в таком случае извиняюсь. К вам в профиль не заглядывал. Да и вроде как не троллил, пытался просто пообсуждать. Впрочем, всего доброго, эта ветка явно изжила себя.
К сожалению, вы не совсем понимаете мой вопрос. Я упоминаю defer только как механизм для гарантированного закрытия, не более. Я не говорю, что он обязателен для чего-либо. Мой вопрос хотя бы о минимальной ситуации, когда переменная, содержащая неуправляемый ресурс, была создана (не передана снаружи) внутри функции, не "ушла наружу" и при этом не была корректно закрыта. По моему опыту, такая ситуация довольно часто встречается в реальном коде.
Окей, тут согласен. Давно не писал, возможно так и было. Впрочем, вопрос boilerplate остаётся, хоть и не так остро.
Всем устраивает. Кроме того, что последний раз, когда я имел дело с Go, компилятор никак не предупреждал, что я его пропустил. Или ситуация поменялась, и я напрасно ною?