LINUX.ORG.RU

Почему void* не нужен?

 , ,


0

2

Смеркалось.

Пятница.

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

Что можно сделать плохого? Явно привести ни к тому типу? Ну так и в плюсах можно. Разименовать нулевой? См. предыдущий пункт.

Что еще?

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

ы, видимо, слишком мало овощей в жизни резал.

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

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

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

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

Дефект мозолистого тела? Понял, учёл. Не переживай, за это даже инвалидность не дают.

EDIT: Извини, вые***ться захотелось. xD Больше не буду. Сегодня.

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

однако это же тоже не бесплатно: плюсы стократно сложнее со всеми вытекающими

внезапно до тебя дошло, что инженерия - это сполошные компромиссы и отсутствие серебрянной пули?

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

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

Да, можно. Но, как по мне, это не аргумент в защиту — явный каст на то и явный, что разработчик делает его осознанно (на самом деле нет, но это тема отдельного мини-срача). А я отвечаю на вопрос из ОП-поста:

Почему void* не нужен?

Потому что ему есть лучшие альтернативы (в общем случае — шаблоны)

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

А ты гарантируешь, что не подцепишь какую-нибудь хрень, если будешь всё жрать немытыми руками?

Руки-то я мою. А вот овощи режу – ножом, хоть это и не безопасно

Никакой не детский сад: именно в этом и посыл, не перебарщиваете ли вы с безопасностью, когда мы говорим о низкоуровневых опасных инструментах – сколько не далай нож безопасным в основе своей он останется ножом и «выстрелить себе в ногу» можно будет всегда, что мы и видем на примере плюсов, так стоила ли овчинка выделки еслои мы в итоге получили инструмент с поможщью которого можно точно так же себя порезать, тока он стократно сложнее?

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

ну так ведь можно явно кастануть не туда что угодно в что угодно в плюсах.

Если правильно код писать, то компилятор тебе не даст.

Вооооот. Но ведь если правильно код писать – то он тебе и на сях не даст. Я к этому и веду

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

Вооооот. Но ведь если правильно код писать – то он тебе и на сях не даст. Я к этому и веду

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

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

Пиши на джаве тогда

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

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

внезапно до тебя дошло, что инженерия - это сполошные компромиссы и отсутствие серебрянной пули?

Неее, давно дошло, я хотел чтоб воид покритиковали, а вы мне рассказывете только то, что я и сам заню – никакого толку от вас :)

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

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

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

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

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

Звучит как «Компилятор не проверит правильно ли я хожу по массиву, это на моей совести, зато я получу возможность использовать арифметику указателей в простом и понятном си». А потом твое имя на доске почёта CVE.

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

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

нет, не перебарщиваем. Если ты не заметил, C++ занял ту нишу, которая сейчас с C очень слабо пересекается (не в смысле использования сишных библиотек, а в смысле «вся система на С» vs. «вся система на C++». Когда C++ был на пике своего роста, он быстро занял нишу десктопных приложений, игр. Сишка при этом осталась в ядре и маломощной встраивальщине. Во всяком случае, из ядра её никто не вытеснил, а плюсы в ядре - это очень кастрированные плюсы.

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

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

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

Если ты пишешь на си, то мнение плюсовиков о void* не важно. В сишке нет шаблонов (которыми в плюсах обычно реализуют все ADT, естественным образом решая проблемы с кастами). В сишке нет штук типа std::variant, нет умных указателей, нет std::function, нет вообще почти ничего типобезопасного. Поэтому void* в сишке и в плюсах — вещи совершенно разные: в первом случае это обычный инструмент, во втором — опасная низкоуровневая игрушка, которую во многих случаях можно чем-то адекватно заменить

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

Если ты пишешь на си, то мнение плюсовиков о void* не важно.

Ещё лучше так: если применение C целесообразно по всей сумме факторов, мнение плюсовиков о частностях не имеет веса.

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

стоило бы запилить в стандартную поставку структуры данных, с опорой на сабж

Если ты про контейнеры в стиле GLib, то у них с эффективностью не особо. Хорошо у интрузивных в стиле queue.h, но они на хаках с UB, в стандарт такое не положишь. Но там не void*.

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

Я не буду выходить за границы массива, мамой клянус!

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

u5er ★★
()

ну не размахивай рукой, гогда у тебя в руке нож

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

rupert ★★★★★
()

Может быть потому, что в C++ указатель на метод может занимать больше 8 байтов? Такой в void* не сохранишь.

Хотя зачем нужен void* в C я тоже не понимаю. Есть же char *, можно к нему всё кастовать было бы, и потом назад.

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

А что в нем синтетического? Алгоритмы и структуры данных – это основа любой программы, а в сишки они все на void* будут.

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

vbr ★★★★
()

не размахивай рукой, когда у тебя в руке нож

1. Должен ли быть в языке нож? Вопрос вкуса. Кто-то считает, что программисту можно доверять, кто-то - что лучше не.

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

Вопрос вкуса.

svu ★★★★★
()

в самом void* нет ничего злого. Просто указатель на куда-то в память.

зло исходит от повсеместных struct fruit { void *next ; ... }. Когда к непосредственным свойствам сущности «фрукт», добавляют нелепую связь с другой сущностью.

Даже если там не void* а struct friut*, всё равно это ведёт в архитектурный тупик и тормоза. Даже если там shared_ptr и обмазано шаблонной магией

MKuznetsov ★★★★★
()

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

Ну получил он void*, ну и что дальше с ним делать, когда и во что кастовать? Это тупо трата времени на курение доки и исходников, которой можно было бы избежать.

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

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

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

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

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

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

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

зло исходит от повсеместных struct fruit { void *next ; … }. Когда к непосредственным свойствам сущности «фрукт», добавляют нелепую связь с другой сущностью.

тут надо писать так

struct fruit {
  ....
}

struct fruit_list_node {
  fruit_list_node *_next;
  fruit _fruit;
}

и второй тип можно сделать простой макрой… это если мы остаемся внутри си. и никаких тупиков

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

Ну да, весь смысл в том, чтобы можно было неявно кастовать между void * и anything *, если сделать неявный каст между char * и anything * будет немного странно. Ладно, пусть будет.

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

у тебя есть каст по умолчанию из some_type* в void*, потому ты можешь без проблем писать free(some_type_ptr). любой поинтер по дефолту кастуется в void*. void* это обобщенный указатель или просто физический адрес.

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

Хотя зачем нужен void* в C я тоже не понимаю. Есть же char *, можно к нему всё кастовать было бы, и потом назад.

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

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

«выстрелить себе в ногу» можно будет всегда, что мы и видем на примере плюсов

Нелюбят сишку за опасность только тролли. Нормальные люди выбирают современный (это важно) C++ за читабельность и поддерживаемость. Ато довелось тут читать код одного электронщика на си, так проще написать алгоритм с нуля, чем переписать это.

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

Например, говорят (говорят!) что в си нет стандартных, например, списков, потому что их можно реализовать в общем случае только с помощью макросов или воид*

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

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

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

Никакого отличия от void*. Указатель на void* точно так же может быть не выровнен и точно так же могут быть проблемы.

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

Твоя реализация универсальна но она содержит оверхед. Безоверхедная реализация это встроить указатель next (или next+prev) в сам payload, а иногда и несколько их если структура в нескольких списках одновременно. А вот если количество списков, в которых участвует структура, заранее неизвестно, то остаётся наверно только твой вариант со всеми его минусами.

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

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

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

struct payload{
   struct item next;
   ...
};

Таким образом, item используется только для работы списка, а для доступа он просто приводится к типу struct payload* и уже идёт обращение к нему.

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

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

u5er ★★
()
Ответ на: комментарий от svu
  1. Должен ли быть в языке нож? Вопрос вкуса. Кто-то считает, что программисту можно доверять, кто-то - что лучше не.

Так C сам по себе нож. Точнее, стул. С пиками точёными. (А второй, разумеется, плюсы)

annulen ★★★★★
()