- 1
- 2
- 3
https://tass.ru/nacionalnye-proekty/6391295
Томские ученые разработали первое в России программное обеспечение, независимое от Windows
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
Всего: 331
+1
https://tass.ru/nacionalnye-proekty/6391295
Томские ученые разработали первое в России программное обеспечение, независимое от Windows
ШОК! Томские ученые открыли способ создавать программное обеспечение, независимое от Windows. Нужно всего лишь…
0
// https://github.com/QWalk/mainline/blob/b12ea3652226caef23c2f5fc7b168746c89096f2/src/system/Pseudopotential_so.cpp#L36
doublevar legendre_so(doublevar x, int n)
{
switch(n)
{
case 0:
return 1;
case 1:
return x;
case 2:
return .5*(3*x*x-1);
case 3:
return .5*(5*x*x*x - 3*x);
case 4:
return 0.125*(35*x*x*x*x -30*x*x +3);
case 5:
return 0.125*(63*x*x*x*x*x - 70*x*x*x + 15*x);
default:
error("Do not have legendre polynomial of order ", n);
return 0; //shouldn't get here, but gets rid of a compiler message
}
}
Вот нет чтоб через шаблоноговно нагенерировать эти свои многочлены Лагранжа.
https://en.wikipedia.org/wiki/Legendre_polynomials#Rodrigues'_formula_and_other_explicit_formulas
Интересно, сколько строк шаблоноговна на это придется потратить?
И вообще, надо чтоб гомоиконность!
+4
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s = "Hellooooooooooooooo ";
std::string_view sv = s + "World\n";
std::cout << sv;
}
https://alexgaynor.net/2019/apr/21/modern-c++-wont-save-us/
What's happening here is that s + "World\n" allocates a new std::string, and then is converted to a std::string_view. At this point the temporary std::string is freed, but sv still points at the memory that used to be owned by it. Any future use of sv is a use-after-free vulnerability. Oops! C++ lacks the facilities for the compiler to be aware that sv captures a reference to something where the reference lives longer than the referent. The same issue impacts std::span, also an extremely modern C++ type.
+2
// https://github.com/WebKit/webkit/blob/e0e7e8f907f4c01c723374e8230a63d46e89e6a0/Source/WebCore/platform/graphics/filters/FEComposite.cpp#L98
static unsigned char clampByte(int c)
{
unsigned char buff[] = { static_cast<unsigned char>(c), 255, 0 };
unsigned uc = static_cast<unsigned>(c);
return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
}
+2
https://habr.com/ru/article/448466/
*/
А последние пару лет набирает популярность boost.hana. Это boost.fusion,
но с constexpr'ом и лямбдами. Автор hana, Луис Дионе (Louis Dionne),
используя на полную мощь все возможности новых стандартов, в некотором
смысле очеловечил метапрограммирование. С помощью hana всяческие
манипуляции с типами, их кортежами, отображениями, а также компайл- и
рантайм-работа с ними обрели практически человеческое лицо и читаемый
вид. Ну, с поправкой на синтаксис C++, разумеется. Вот, например, как выглядит
универсальный сериализатор структур, написанный с помощью hana:
*/
// 1. Give introspection capabilities to 'Person'
struct Person {
BOOST_HANA_DEFINE_STRUCT(Person,
(std::string, name),
(int, age)
);
};
// 2. Write a generic serializer (bear with std::ostream for the example)
auto serialize = [](std::ostream& os, auto const& object) {
hana::for_each(hana::members(object), [&](auto member) {
os << member << std::endl;
});
};
// 3. Use it
Person john{"John", 30};
serialize(std::cout, john);
/*
Ну да, структуры приходится описывать особым образом. А кому сейчас легко?
И тут хочется также отметить библиотеку tinyrefl за авторством Manu Sánchez
(Мануэля Санчеса). Довольно неплохая попытка принести в мир C++-разработки
статическую рефлексию без расширения компилятора. Для своей работы библиотека
требует стороннюю утилиту (cppast), но зато предоставляет довольно удобный доступ
к информации о структурах, которую можно использовать в процессе разработки
программы. Преимущество этой библиотеки (по сравнению с другими) в том, что для
работы с ней не надо использовать «птичий язык», а элементы структур (как и сами
структуры) можно произвольным образом атрибутировать прямо в исходном коде:
*/
struct [[serializable]] Person {
std::string name;
int age;
};
template<typename Class>
auto serialize(std::ostream& os, Class&& object) -> std::enable_if_t<
tinyrefl::has_metadata<std::decay_t<Class>>() &&
tinyrefl::has_attribute<std::decay_t<Class>>("interesting"),
std::ostream&>
{
tinyrefl::visit_member_variables(object, [&os](const auto& /* name */, const auto& var) {
os << var << std::endl;
});
return equal;
}
/*
Таких примеров можно привести ещё много (или найти на гитхабе или гитлабе).
Объединяет все эти библиотеки и инструменты одна особенность: значительно
облегчая жизнь своим пользователям, они имеют такую реализацию, что остаётся
лишь предполагать, какое количество страданий испытали их разработчики. Достаточно
заглянуть в реализацию, увидеть забор из ifdef'ов и угловых скобок — и всё понятно.
Нередко эти реализации делаются на грани возможностей компиляторов. workaround'ы
банальных ошибок (или особенностей реализации языка конкретной версии конкретного
компилятора с конкретными флагами) здорово раздувают их код. Желание поддерживать
несколько стандартов сразу заставляет придумывать зубодробильные конструкции.
Безусловно, простая попытка реализовать что-нибудь подобное здорово поднимает уровень
владения языком (иногда — и самооценку). Но в какой-то момент, после многочасовой возни
с очередной ошибкой, или непроходящим тестом, или крэшем компилятора руки опускаются,
хочется плюнуть и бросить, ибо силы бороться иссякают.
*/
Именно поэтому я за гомоиконность
+1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(void)
{
uint32_t a = 24804541;
for(size_t i = 0; i < 5; i++)
{
for(size_t j = 0; j < 5; j++)
{
putchar( "01"[(a >> (i*5 + j)) & 1]);
}
putchar('\n');
}
return EXIT_SUCCESS;
}
https://ru.wikipedia.org/wiki/Параграф_86а_Уголовного_кодекса_Германии
> В 1998 году суд Франкфурта-на-Майне своим решением запретил распространение компьютерных игр, в которых содержится какая-либо нацистская символика — прецедентом стала игра Wolfenstein 3D. Немецкие локализаторы вынуждены были заменять в играх нацистскую символику на другие символы, не попадающие под нарушение параграфа 86а Уголовного кодекса Германии.
Предлагаю запретить число 24804541.
+1
#include <stdio.h>
#include <stdlib.h>
void myfree(void *ptr)
{
printf("%p\n", *(void **)ptr);
free(*(void **)ptr);
printf("freed!\n");
}
int main(void) {
char *x __attribute__ (( cleanup (myfree) )) = malloc(1);
printf("%p\n", x);
return 0;
}
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
cleanup (cleanup_function)
The cleanup attribute runs a function when the variable goes out of scope. This attribute can only be applied to auto function scope variables; it may not be applied to parameters or variables with static storage duration. The function must take one parameter, a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
If -fexceptions is enabled, then cleanup_function is run during the stack unwinding that happens during the processing of the exception. Note that the cleanup attribute does not allow the exception to be caught, only to perform an action. It is undefined what happens if cleanup_function does not return normally.
+3
Решил я значит от нехуй делать нарисовать свой пиксельный шрифт
(кому интересно - вот промежуточный результат https://i.imgur.com/2vIJoio.png)
и решил посмотреть, какие там вообще бывают под GNU/Linux редакторы для
шрифтов, и какие вообще шрифты бывают
Так вот, нашел я вот такую хрень http://mensis.sourceforge.net/overview.html
Вижу, что там какой-то ассемблер http://mensis.sourceforge.net/ttfcv-all.png или
байткод ебаный. Погуглил по этим говноинструкциям со скриншота:
Оказывается в TTF шрифтах есть встроенный тьюринг-полный ЯП, используемый
для всяких там подсказок, типа "куда дорисовать пиксель вот при таком-то условии"
и прочая подобная херота
А еще в шиндошс (до Windows 10) этот шрифтоговнобайткод интерпретировался в
пространстве ядра (ну тупыыые..) и разумеется таким образом удалось винду хакнуть
https://security.stackexchange.com/a/91395 (разве могло быть иначе?)
про шрифтоговнобайткод можно почитать например тут
https://docs.microsoft.com/en-us/typography/opentype/spec/tt_instructions
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM05/Chap5.html#instructions
На кой вообще хер делать тьюринг-полный язык для отрисовки глифов? Ну и раз вы его уже
делаете, то заебошьте там что-нибудь на основе LLVM байткода, чтоб JIT, или вообще все глифы
сразу компилировать в натив, или даже (чего мелочиться) под GPU. Типа мы хотим
нарисовать какую-то букву с размером 10 - вызываем функцию
drawA(10, bufptr, x, y); - рисуется десятого размера буква в буфер. И никаких непонятных
говнобайткодов. Четко и дерзко!
+4
#include <inttypes.h>
auto a(auto b) __attribute__ ((noinline));
auto a(auto b)
{
return b*1.5;
}
double test1(double in)
{
return a(in);
}
uint64_t test2(uint64_t in)
{
return a(in);
}
/*
https://godbolt.org/z/6ZQAnv
auto a<double>(double):
mulsd xmm0, QWORD PTR .LC0[rip]
ret
test1(double):
jmp auto a<double>(double)
auto a<unsigned long>(unsigned long):
test rdi, rdi
js .L5
pxor xmm0, xmm0
cvtsi2sd xmm0, rdi
mulsd xmm0, QWORD PTR .LC0[rip] # хули ты мне плавучего питуха в xmm0 возвращаешь?
ret
.L5:
mov rax, rdi
and edi, 1
pxor xmm0, xmm0
shr rax
or rax, rdi
cvtsi2sd xmm0, rax
addsd xmm0, xmm0
mulsd xmm0, QWORD PTR .LC0[rip]
ret
test2(unsigned long):
sub rsp, 8
call auto a<unsigned long>(unsigned long)
movsd xmm1, QWORD PTR .LC1[rip]
comisd xmm0, xmm1
jnb .L8
cvttsd2si rax, xmm0 # ну нахуй тут надо double в uint64_t конвертить
add rsp, 8 # почему это не делается в auto a<unsigned long>(unsigned long)
ret
.L8:
subsd xmm0, xmm1
add rsp, 8
cvttsd2si rax, xmm0
btc rax, 63
ret
.LC0:
.long 0
.long 1073217536
.LC1:
.long 0
.long 1138753536
*/
концепты-хуепты
+5
/*
https://habr.com/ru/company/jugru/blog/444212/
Александр: Я не думаю, что существует какое-то одно «правильное» определение ФП,
но если говорить лично обо мне, то ФП — это нечто с функциональной композицией и
функциями первого класса.
Иван: Я согласен, но добавил бы ещё функции высшего порядка — те, которые могут
принимать другие функции в качестве аргументов и возвращать как результат.
Cергей: Ссылка на функцию в Си — считается?
Иван: Нет, Си не является функциональным языком программирования :-)
Сергей: Расскажи, почему?
Иван: Потому что нельзя из комбинации указателей на функции создать новую функцию,
можно только указывать на уже существующие. Конечно, если в ход не пошли какие-то
ассемблерные хаки.
*/
#include <stdio.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#define FUNC(a, ...) typeof( a (*) (__VA_ARGS__) )
uint64_t mul2(uint64_t a)
{
return a*2;
}
uint64_t add2(uint64_t a)
{
return a+2;
}
uint64_t chaincaller(uint64_t a, typeof(uint64_t (*)(uint64_t)) *chain)
{
while(*chain != NULL)
{
a = (*chain)(a);
chain++;
}
return a;
}
FUNC(uint64_t, uint64_t) *combine_fn (FUNC(uint64_t, uint64_t) a, FUNC(uint64_t, uint64_t) b)
{
FUNC(uint64_t, uint64_t) *funchain = (FUNC(uint64_t, uint64_t) *)malloc(sizeof( FUNC(uint64_t, uint64_t) [3]) );
if (funchain == NULL)
{
exit(ENOMEM);
}
funchain[0] = a;
funchain[1] = b;
funchain[2] = NULL;
return funchain;
}
int main(void)
{
FUNC(uint64_t, uint64_t) *func_chain = combine_fn(mul2,add2);
uint64_t a = 15;
uint64_t b = chaincaller(a, func_chain);
printf("%" PRIu64 " * 2 + 2 = %" PRIu64 "\n", a,b);
free(func_chain);
return 0;
}
Ассемблерные хуяки.
https://wandbox.org/permlink/gdRggB77GQOiNzyJ
Он так говорит, будто б в крестоговно впилили какой-то недоJIT, который честно может сгенерить одну функцию из двух.