- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
typedef struct list list;
struct list
{
list* next;
uint32_t data;
};
#define ADD_LIST(ptr, val) \
do { \
(ptr)->next = (list *)alloca(sizeof(list)); \
(ptr)->next->data = val; \
(ptr)->next->next = NULL;\
} while (0)
// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
#define INIT_LIST(val) \
({ \
list *INIT_LIST = (list *)alloca(sizeof(list)); \
INIT_LIST->data = val; \
INIT_LIST->next = NULL; \
INIT_LIST; \
})
int main(void)
{
list *a = INIT_LIST(5);
ADD_LIST(a,10);
ADD_LIST(a->next,15);
ADD_LIST(a->next->next,20);
ADD_LIST(a->next->next->next,25);
ADD_LIST(a->next->next->next->next,30);
for(list *ptr = a; ptr != NULL; ptr = ptr->next)
{
printf("%d ", ptr->data);
}
return EXIT_SUCCESS;
}
j123123 19.07.2021 10:36 # 0
ASD_77 19.07.2021 17:30 # 0
j123123 20.07.2021 08:43 # +4
И кстати LLVM IR тоже говно. Попробуй на нем "Сетунь" описать - нихуя не выйдет, потому что в LLVM IR есть какие-то "биты", а в "Сетунь" никаких битов нет. https://govnokod.ru/23305#comment389657
3.14159265 11.08.2021 17:43 # 0
На VLA переписать нельзя?
MAKAKA 11.08.2021 17:47 # 0
Либо alloca, либо тогда уже кресты и std::vector
j123123 11.08.2021 17:47 # +1
MAKAKA 11.08.2021 17:50 # 0
j123123 11.08.2021 17:56 # +2
MAKAKA 11.08.2021 17:57 # 0
У меня в C++03 всё работает
j123123 11.08.2021 17:58 # 0
VLA не позволяет ничего довыделить. Разве что рекурсией можно, но тогда и VLA нахуй не нужно.
3.14159265 11.08.2021 18:20 # +1
Но, кмк, кроме всех бед alloca c инлайнами её главная проблема в семантике разврата.
В отличие от malloc, который хотя бы NULL вернёт, если память кончилась.
alloca делает невозможным написание хотя бы подобия безопасного кода. Во-1 стек тихо переполняется, во-2 поведение при этом не определено.
MAKAKA 11.08.2021 18:32 # 0
int petuh[get_the_biggest_number()];
j123123 11.08.2021 19:07 # 0
MAKAKA 11.08.2021 19:12 # 0
Функция возвращает какое-то очень большое число. Оно правильного типа, но стек уже переполнился. Что будет?
j123123 11.08.2021 19:37 # 0
Если ты потом еще что-то навыделяешь на стеке даже без VLA, оно может разместиться после той хуйни, и если ты туда что-то поназаписываешь, будет падение. Хотя можно и так напереполнять, что можно дотянуться до хипа, и тогда можно туда какой-то хуйни насрать, обойдя guard page
MAKAKA 11.08.2021 19:55 # 0
А в куче можно на нул проверить
>. Хотя можно и так напереполнять, что можно дотянуться до хипа,
На x64 это наверное надо очень наглым быть
j123123 11.08.2021 19:05 # 0
У тебя и при глубокой рекурсии стек переполняется, так что это один хер. Выходит, использование вызова функций делает невозможным написание хотя бы подобия безопасного кода? Хотя можно большой массив на стеке и в одной основной функции написать, так что для безопасного кода лучше вообще не писать ничего.
1024-- 11.08.2021 19:07 # +1
Я не Пи, но сказал бы "да".
В том же жс есть исключение про переполнение стека, которое можно поймать и обработать.
Но нет исключения про переполнение кучи, поэтому new просто убивает программу.
3.14159265 11.08.2021 19:09 # +1
В таком случае максимальная глубина стека статически вычисляется при сборке программы.
То есть строго фиксирована не зависит от пользовательских данных, пришедших в scanf.
Таким образом введя хуеву тучу данных ошибку нехватки памяти можно корректно обработать и программу нельзя внезапно закрашить с buffer overflow.
j123123 11.08.2021 19:15 # 0
Это можно и в случае с выделением на стеке сделать, обработав соответствующий сигнал, когда память пытается читаться и/или записываться в "guard page" https://dave.cheney.net/wp-content/uploads/2015/08/threads.png
PolinaAksenova 11.08.2021 19:48 # 0
Это всего лишь иллюзия безопасности. Выделяешь большой массив через VLA, пишешь ему в конец — всё, някаких "guard page" там нят, всё сломалось.
Об этом был как-то большой разговор ня ГК.
j123123 11.08.2021 19:51 # 0
Это вполне решается "протыкиванием" памяти перед первым реальным обращением в VLA. Ну и если в рантайме программе известно, в каком адресе стек кончается - можно это тупо проверять.
И никакого VLA тут не нужно. Такая же питушня будет с обычным выделенным на стеке массива большого размера
PolinaAksenova 11.08.2021 19:54 # −1
Уж лучше тогда реальня проверять границу стека, это хотя бы одно сравнение.
j123123 11.08.2021 19:54 # 0
PolinaAksenova 11.08.2021 19:57 # −2
Собствення, выделение 65 килобат — вполне себе обычняя операция, и уже в этом случае пробинг нячинает сливать.
j123123 11.08.2021 19:59 # 0
PolinaAksenova 11.08.2021 20:01 # −2
j123123 11.08.2021 20:07 # 0
https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details
являются на данный момент (Current 48-bit implementation) невалидными на всех существующих процессорах с архитектурой x86-64, и это можно использовать как "guard page", потому что там просто нихуя нет.
MAKAKA 11.08.2021 20:14 # 0
С одной стороны стек, с другой -- куча, а по середине естественная граница, а?
j123123 11.08.2021 20:29 # 0
Ну и вся эта идиллия нахрен ломается, если у нас несколько процессов на одном адресном пространстве, и у каждого свой стек в нем.
1024-- 11.08.2021 20:19 # 0
Существительное, неодушевлённое, средний род. Происходит от гл. собствети, далее из праслав. *sobstveti «някять; понякивать»
(Вяки-слонярь)
j123123 11.08.2021 19:19 # 0
JloJle4Ka 19.07.2021 10:39 # 0
j123123 19.07.2021 10:42 # 0
JloJle4Ka 19.07.2021 10:43 # 0
j123123 19.07.2021 10:44 # 0
JloJle4Ka 19.07.2021 10:44 # 0
j123123 19.07.2021 10:46 # +3
GravatarGovno 19.07.2021 10:55 # +2
Кстати, есть пример, когда do { ... } while(0) имеет смысл в обычном коде: break или continue досрочно завершает выполнение блока, и не нужно лепить goto или косяки вложенных ифов.
JloJle4Ka 19.07.2021 11:01 # 0
bormand 19.07.2021 11:02 # 0
JloJle4Ka 19.07.2021 11:03 # 0
bormand 19.07.2021 11:04 # 0
JloJle4Ka 19.07.2021 11:10 # 0
bormand 19.07.2021 11:11 # 0
JloJle4Ka 19.07.2021 11:13 # 0
А, нет, это про другое написано.
> It doesn't help to wrap things in curly braces within the macro, because a semicolon after the braces is syntactically incorrect.
Решение проблемы довольно просто́: не ставить «семиколон» после мокроса.
bormand 19.07.2021 11:16 # 0
Именно поэтому я за do while.
Но, повторюсь, в твоём примере expression а не statement.
JloJle4Ka 19.07.2021 11:27 # 0
Это, кстати, даже к лучшему: вот захочешь ты взять указатель на функцию... А это мокрос. Да и правило простое: после мокроса скмиколон не ставится.
guest6 19.07.2021 11:14 # +2
bormand 19.07.2021 11:18 # 0
Второй макрос же в ({...}) завернут. Все норм с ним, просто гнутое расширение требует.
JloJle4Ka 19.07.2021 11:21 # 0
Оператор post-goatse.
А разве он не в «{}» завёрнут? Или мокрос кончается на первой попавшейся пустой линии?
> Линии
Ну вот, скоро начну и «аппликации» говорить (((
bormand 19.07.2021 11:26 # 0
JloJle4Ka 19.07.2021 11:32 # 0
#define KOKO (body)
guest6 19.07.2021 11:36 # +2
bormand 19.07.2021 11:40 # +1
GravatarGovno 19.07.2021 11:47 # +1
bormand 19.07.2021 12:27 # +2
GravatarGovno 19.07.2021 13:35 # +2
Привык, что сишке/крестам плевать на пробелы.
JloJle4Ka 19.07.2021 13:49 # 0
echo 2+2 * 3+3
GravatarGovno 19.07.2021 13:52 # 0
Так?
А звёздочка будет означать по-прежнему умножение или что-то другое?
Desktop 19.07.2021 13:57 # +2
bormand 19.07.2021 14:04 # +2
JloJle4Ka 19.07.2021 14:08 # 0
А что выведет такой код, угадаешь?
bormand 19.07.2021 14:20 # +2
Ну блин, скучно. Везде ведь так.
JloJle4Ka 19.07.2021 14:22 # 0
gologub 19.07.2021 14:39 # +2
nuTepcKuu_nemyx 19.07.2021 10:49 # +2
ASD_77 19.07.2021 17:31 # 0
guest6 19.07.2021 17:37 # 0
j123123 20.07.2021 04:25 # +4
bormand 19.07.2021 10:44 # +1
j123123 19.07.2021 10:48 # +1
bormand 19.07.2021 10:54 # 0
Всё-таки тут надо было именно динамичный пример показать, что ты создаёшь ноды на лету и не знаешь о них ничего заранее.
j123123 19.07.2021 11:49 # +1
Или надо чтобы что-то из stdin считывалось и в такой список упихивалось?
bormand 19.07.2021 12:32 # 0
j123123 19.07.2021 12:50 # +1
Теперь список с нулем элементов это не когда указатель на такой список равен NULL, а когда ->next равен NULL. И INIT_LIST() теперь нихрена не принимает в качестве первого значения
bormand 19.07.2021 13:02 # +1
ASD_77 19.07.2021 19:09 # +1
bormand 19.07.2021 19:14 # 0
MAPTbIwKA 19.07.2021 19:15 # +1
j123123 19.07.2021 22:46 # +1
bormand 19.07.2021 22:55 # 0
KOTuK 02.08.2022 21:02 # 0
MAPTbIwKA 19.07.2021 22:57 # 0
j123123 19.07.2021 23:00 # 0
MAPTbIwKA 19.07.2021 23:02 # 0
Ты ведь тоже можешь стековерфлоу схватить
j123123 19.07.2021 23:03 # 0
MAPTbIwKA 19.07.2021 23:13 # 0
j123123 19.07.2021 23:33 # 0
https://hackaday.com/2015/06/29/true-random-number-generator-for-a-true-hacker/
> When power is applied to the MCU, its internal volatile RAM has unknown contents. Each flip-flop will be preset to a 0 or 1 state – a consequence of the imperfection of internal circuits, power supply glitches, surrounding current flow, or thermal (or even quantum) noise. That’s why the content of RAM is different each time it is powered on.
Так что для BSS тебе нужен код зануления, а дня инициализированной (если это RAM) тебе нужен код, который из флеша перекопирует в RAM.
gologub 19.07.2021 23:51 # 0
его вздрючат
ru66oH4uk 20.07.2021 00:49 # 0
Как разделяется адресное пространство с точки зрения сей, кстати?
j123123 20.07.2021 03:25 # +1
Это implementation и platform dependent хуйня. Компиляторы могут всякие там директивы поддерживать. GCC и keil например имеет какие-то __attribute__((section("name")))
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
https://www.keil.com/support/man/docs/armcc/armcc_chr1359124982450.htm
В AVR у GCC еще есть https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html такая хуйня, ведь там адресное пространство под флеш и адресное пространство под оперативку разное
Под линуксом можно в объектные файлы насрать всяких разных секций и потом через линкер-скрипт это как-то там собирать можно https://users.informatik.haw-hamburg.de/~krabat/FH-Labor/gnupro/5_GNUPro_Utilities/c_Using_LD/ldLinker_scripts.html
ru66oH4uk 20.07.2021 03:35 # 0
j123123 19.07.2021 23:53 # +1
Есть всякие дешевые лог. анализаторы на базе этого контроллера, и там прошивка в оперативку заливается по USB при каждом включении.
bormanb 02.08.2022 23:15 # 0
hormand 02.08.2022 21:54 # 0