На мой взгляд, наилучший вариант — возвращать статический буфер. Минусы: в клиенском коде зачастую придется копировать эту строчку, плюс в многопоточном варианте скорее всего будет ой-ой. Варианты возврата динамически выделенного буфера и модификации API отметаем. Говорят, есть вариант получе. Найти не смог, сами ответ мне не дали, сославшись на то, что не комментируют корректность ответов. Кроме этих трех вариантов ничего в голову не приходит, да и не гуглится. Ваши варианты?
Молодец, уже настрочил пока я писал. Только вот 2проблемы - возвращать надо не buf, а чуть дальше, чтобы дебильчик не получил анальную боль дебагая даблфри в твоей функции, заюзав где-то фри на возврат.
Реализация маллока не обязательно на каждый тред имеет свою кучу, поэтому это может течь и без синхронизации не будет гарантированно нормально работать.
Ниужели после всего, что между нами было - ты смеешь мне ещё что-то писать. Ты полностью показал и доказал свою профнепригодность, зачем ты комментируешь мои сообщения вызывая меня на срач?
За шкафом! Если ты не поставишь константе модификатор const, она вместо флеша будет торчать в оперативке, засирая ее! И ладно, если у тебя десяток-другой переменных. А если это структура на сто килобайт?
Это только для глобалов и статиков - раз. В данном случае нет ни глобала ни статика, а тот факт, что в каком-то говне юзается родата не делает конст нужным - это просто кастыль.
И да, в гцц есть атрибут который позволяет куда угодно тебе тебе и что угодно записать. Это в 10раз более удобно чем через говноконст с тонной говна в родате.
А если это структура на сто килобайт?
Ну если ты ваяешь как маздайщик через идеешечку и ничего не знает про лд и не можешь запихнуть свои сто киллобайт куда следует - ну это твоя проблема.
У меня таких проблем нет, я не юзаю кастыльное и протухшеубогое с89 и не жру говна с кастылей убогих.
И да, я тебя не обижаю, просто есть более удобные способы, но ты можешь делать по старинке. Я тебя нивчем не обвиняю, не пичалься - ты хороший, а хорошим надо дружить не обижаться на меня. ^_^
конст в сишке пишут только низкоквалифицированные специалисты
Если есть возможность сказать компилятору, что данные не должны изменяться (например, передача массива в функцию только для чтения), то это нужно делать.
Реализация маллока не обязательно на каждый тред имеет свою кучу, поэтому это может течь и без синхронизации не будет гарантированно нормально работать.
А причём тут треадсейв? Тут дело не в нём. Тут дело в реализации этого самого треадсейва. Это может быть либо у каждого треда своя хипа, либо общий хип.
Давай я тебе объясню в чем проблема, скорее всего тут:
static _Thread_local char *buf;//будет уникальна всегда, с каждым созданием треда.
Т.е. если мы заспавни твой воркер 100500 раз - у нас будет 100500 маллоков, которые никто не удалит. Возможное решение - это в случае с уникальной куче - это уничтожение кучи при завершении нити.
Это решение не факт, что есть даже у маллока с уникальным хипом для каждого треда, а вот у решения с общим хипом точно нет.
Поэтому это будет течь. Т.е. значение переменной buf из завершеного потока не наследуется следующему созданному, а должно.
Тут штука в том, что мои утверждения относятся только к реальным пацанам, а старообрядцев я ввиду не имею. У пацанов там 100500 *.c файлов, у пацанов там до сих пор линковка, у пацанов там инлайн ещё не случился. Если ты относишься к ним - мои утверждения к тебе не относятся.
(например, передача массива в функцию только для чтения)
И что это даст? Это ничего не даст.
то это нужно делать.
Кому это нужно и зачем? Мне не нужно. А объяснить почему это нужно тебе - ты не объяснил. Т.е. это блажь, а блажь и нужно это совершенно разные вещи.
Также программист, когда видит такое, понимает, что в функции ничего из переданного не изменяется.
Жабист чтоли? О работе функции говорит логика, либо если с ней плохо, либо код писал низкоквалифицированный старообрядец, то да - есть документация и сырец.
И да, это относиться только ко внешнему апи и там ты можешь писать как хочешь/по уставу/талмуду, либо как-то ещё. Это всё твои субъективные заморочки.
Если же во внутреннем коде пацаны не знаю что делают и как работают их функции, ну это кастыль и никакой объективной причинности не имеет. Т.е. это ваши субъективные заморочки.
Ещё раз, я тебе не запрещаю жить в своём мире эльфов и мистических конпеляторов, верить в свою религию и талмуд. Только научитесь не приравнивать свой мир ко миру всему, хорошо?
А без приведения типов? Приведение типов сразу говорит о том, что с кодом что-то не так, поэтому пример крайне некорректен. Приводи корректные примеры, пожалуйста.
lol.c: In function ‘foo’:
lol.c:2:3: error: implicit declaration of function ‘memmove’ [-Werror=implicit-function-declaration]
memmove((char *)buf, buf + 5, strlen(buf));
^
lol.c:2:3: error: incompatible implicit declaration of built-in function ‘memmove’ [-Werror]
lol.c:2:3: error: implicit declaration of function ‘strlen’ [-Werror=implicit-function-declaration]
lol.c:2:33: error: incompatible implicit declaration of built-in function ‘strlen’ [-Werror]
memmove((char *)buf, buf + 5, strlen(buf));
^
lol.c: In function ‘main’:
lol.c:9:3: error: implicit declaration of function ‘fprintf’ [-Werror=implicit-function-declaration]
fprintf(stderr, "%s\n", str);
^
lol.c:9:3: error: incompatible implicit declaration of built-in function ‘fprintf’ [-Werror]
lol.c:9:11: error: ‘stderr’ undeclared (first use in this function)
fprintf(stderr, "%s\n", str);
^
lol.c:9:11: note: each undeclared identifier is reported only once for each function it appears in
cc1: all warnings being treated as errors
Обделался и в кусты? Что значит без приведения типов? Приведение типов валидная и основная операция. Ну и да, автокаст из const во что угодно валидная операция, и максимум, что можешь сделать конпелятор - высрать тебе ворнинг.
Приведение типов сразу говорит о том, что с кодом что-то не так, поэтому пример крайне некорректен.
Ну конечно же, мистер школьник так много понимает в коде.
Приводи корректные примеры, пожалуйста.
Я вон не понимаю, зачем при обсёре ты начинаешь юлить? Тыж кукарекнул конпелятор не позволит, а тут вдруг не позволить я должен себе сам.
максимум, что можешь сделать конпелятор - высрать тебе ворнинг.
Если будет warning, значит нужно использовать.
Пример по прежнему некорректен.
mikhail@lens ~/dev $ gcc -Wall -Wpedantic -Werror test3.c
test3.c: В функции «foo1»:
test3.c:27:3: ошибка: инициализирующий элемент не может быть вычислен во время компоновки [-Werror]
ptr_t t = {buf};
^
cc1: all warnings being treated as errors
Хорошо, посмотрел на тот, который собирается. Об отсутствии необходимости использования const он не говорит. По типу функции видно, что программист не планирует изменять buf, следовательно, сразу видна ошибка.
Ты посмотрел на оба, и сделал вид, что типа второй не работает, хотя это твой файл.
Об отсутствии необходимости использования const он не говорит.
Причём тут «отсутствии необходимости использования» - он говорит о фейле в твоём балабольстве,а именно:
Компилятор не позволит ни изменить сам указатель внутри функции, ни изменить значение массива.
Меня абсолютно не интересует что там у школьников необходимо, а что нет.
По типу функции видно, что программист не планирует изменять buf, следовательно, сразу видна ошибка.
Какая нахрен ошибка? Причём тут ошибка? Чтож ты сливаешься и юлишь как первоклассник?
Есть факты - ты сказал, что конпелятор чего-то там не позволит - ты сел в лужу, т.е. проболаболил - вывод, ты бабалол, а конст не имеет никакого смысла, кроме каких-то поверий всяких школьников.
Ты можешь там в своём мире наделять его чем угодно - есть конкретный факт - конст в сишке ничего не гарантирует и объективно нахрен не упал.