duangsuse::Echo
583 subscribers
4.12K photos
118 videos
579 files
6.13K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
因为无效我就不继续折腾了... 我写个 JSON Parser 先吧... (汗)

那么我们来学学使用 #C CMake:

cmake_minimum_required(VERSION cmake_min_version)
project(project_name)

set(name value)
CMAKE_CXX_FLAGS
Boost_USE_MULTITHREADED
CMAKE_THREADS_LIBS_INIT

find_package(packageName [COMPONENTS {packageName}] [REQUIRED])
PKG_FOUND
PKG_INCLUDE_DIRS
PKG_LIBRARIES

include_directories(dirs)
add_definitions(defs)

if (case)
endif()

add_executable(targetName sources)
target_link_libraries(target libraries)

这就可以用来写简单的 CLI 程序了 🐱
https://github.com/RikkaApps/Riru/tree/master/riru-core/jni/main
#C 欸我真想写一篇分析的... 可惜自己事情又多
很想学学写 C++,虽然我不是真正意义上不会 C++... 只是 C++ 模板和 constexpr 函数式编程比其他不常用一些而已了。
#C 突然想到 C99 还是 C11 开始还有 _align marker...
#C #Windows 我来总结一下用了哪些 API 怎么用,方便背

首先,你需要 aero.h [@ysc3839's gist] 这个 undocumented API header 其中包括必须的数据类型和子程序定义

#CSharp 版:需要使用 C# 的 P/Invoke (System.Runtime.InteropServices)特性

1. 对于外部的 C 结构体,只需要使用 struct 关键字定义,然后加上 [StructLayout(LayoutKind.Sequential)] 特性避免压缩移动优化结构体就可以了
2. 对于外部的 C 子程序,只需要将在一个类里定义的静态方法用 extern 修饰,这个方法加上 [DllImport("user32.dll")] 之类的特性就可以了,如果要指定载入使用的字符编码,需要使用 CharSet(=CharSet.Ansi) 特性指定

Trumeet 的示例还用了一个 [STAThread] 方法特性,只是这个单元只能单线程执行,不过其实不必加在 Main 静态方法上,和 COM 交互的时候加就好了,这个知道就好
simple.c
604 B
#C 随便到网上找了个方法算内联汇编大小
Phonograph
在C语言里,你选择
#c #PLT 一般情况能用 condition 表达式还是不用常量 while+break/continue. (哪怕提前声名量或是用 do while )

说要用的情况就是 main loop ,C 里没闭包就只能用函数指针,或者宏,不优雅不高效,只能选择 while(true) 。 当然是否 #define forever 也是看复用处有多少的。

for(;;) 不喜欢,因为它本应是 for(init;cond;update) ,而 cond 在理论上省略默认 1 是不优雅的(这是语言设计上的不对)

原则上我是讨厌 1 替代 true 的,尽管对许多机器而言非0即真(不过说起来,所谓真假也就是控制流跳转与否而已)。
#c #cxx #gnu glibc 的 math.h 🤔
#C :

#include <stdio.h>
void main(int argc, char** argv) {
for (int i=0; i<0xFF; i++) printf("%c%d", i, i);
}

也可以用 fputc:

void put(int i) {
fputc(stdout, (char) i);
int acc=i; while (acc!=0) {
fputc(stdout, '0'+acc%0xF);
acc /= 0xF;
}
}

这是横向的,当然也可以纵向:

void putTable(int nmax_col) {
int n=0xFF/nmax_col, m=nmax_col;
char ascii[n][m];
for (int j=0; j<m; j++) for (int i=0, i<n, i++) {
ascii[i][j] = (char)j*m+i;
}
for (int i=0, i<n, i++) for (int j=0; j<m; j++) {
char v=ascii[i][j]; printf("%c%d", v,v);
}
}

#asm
.db fmt "%c%d\00"

_main:
push rbp
mov rbp, rsp
sub rsp, 4
mov [rbp-4], 0xFF

for:
mov rax, [rbp-4]
push rax
push rax
push fmt
call printf
dec rax
mov [rbp-4], rax
jnz for

for_out:
add rsp, 4
pop rbp
ret
#c #algorithm #bin 位运算 优化跳空格
glibc strlen.c 默认实现 «Bit Twiddling Hacks>
btw. “减法时间比位运算长”的问题,时间的最小粒度是CPU周期。只需要看这个指令需要几个周期就行了,ALU都是1cycle,比从内存读取快了几个数量级
bool has_zero_byte(uint32_t v)
{
const uint32_t himagic = 0x80808080;
const uint32_t lomagic = 0x01010101;

return ((v - lomagic) & ~v & himagic) != 0;
}

向量实现手写AVX,然而再怎么玩都不如string类型直接存好长度快。
duangsuse::Echo
看最近几条逆天,我要聊哲学 #CS 操作系统不就是4片3口虚拟化么 时间内存存储程序,网口线口板口 #os #plt #embed #recommend win,*nix,mac, aosp ios ;哪个不是只有这么点API和差异化 🦄?为了音视频和回应事件弄那么多框架外链新语法,不如3行 #web js。 像 bellard.org 那样的通才终究少数,搞出\0结尾无长度字串,连{}[]{type:}都没建模的libc算什么API啊?在位运算位flag上都被人打败 也配教人数据结构算法? 。 为这…
#FP #c https://github.com/hirrolot/datatype99/blob/master/datatype99.h macro
https://halfrost.com/reactivecocoa_macro/

tag union: enum { A(int) B(str) } in C 😨 无需任何编译器插件
implemented upon Boost/Preprocessor
冷知识: gcc 宏是可以通过CPS延长递归展开 到1024步的,而宏又包含 if defined/eq 等常规流控与##-concat等运算,意味着即便没有 template<> 魔法, for if 甚至 eval() 也可以 static_assert
// 9, 2, 5
static int lesser_than_10[] = {
ML99_LIST_EVAL_COMMA_SEP(
ML99_listFilter(ML99_appl(v(ML99_greater), v(10)), ML99_list(v(9, 2, 11, 13, 5)))),
};
// 用例: 1+(2+3)
datatype(
BinaryTree,
(Leaf, int),
(Node, BinaryTree *, int, BinaryTree *)
);
int sum(const BinaryTree *tree) {
match(*tree) {
of(Leaf, x) return *x;
of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);
}
}


ML99 是一门在 C99 预处理器运行的lisp https://metalang99.readthedocs.io/en/latest/list.html
尽管如此,有大佬说「元编程」要三思 https://lotabout.me/2018/think-twice-before-utilizing-meta-programming/
btw. 看到文心一言禁止F12, 有人贴了个反制 很有意思😂
for (var i = setTimeout(";"); i-->0; clearTimeout(i)); 


利用宏展开和递归实现貌似不可能的链表处理,其实也只是手段巧妙,利用f.nArg这样的const拼接代码, 效果并不会比过程宏甚至简单的codegen好
#define AND(X, Y) AND_##X##_##Y
#define AND_0_0 0
#define AND_1_1 1

#define IF_ELSE(C, T, E) JOIN(IF_ELSE_, C)(T, E)
#define IF_ELSE_0(T, E) E
#define IF_ELSE_1(T, E) T

#define IF(C, T) IF_ELSE(C, T, )


我还是觉得,如果不限制工具链,编译期反射或运行期记忆化eval 比模板巧妙的多。 体操只是被编译器驯化的结果而已,比递归+模式匹配巧妙的算法有很多。

https://github.com/hirrolot/datatype99/tree/master/examples/derive
https://github.com/orangeduck/CPP_COMPLETE
https://netcan.github.io/2020/11/06/C-Rust元编程之BrainFuck编译器(constexpr-过程宏解法)/

n=a=>a.length
add=(A,B)=>A+B
curry=(f, N=n(f)-1, ARG=Array(N).fill('').map((x,i)=>'_'+i) )=>eval(`p0=>(${ARG})=> ${f.name}(p0,${ARG})`)

curry(add)
p0=>(_0)=> add(p0,_0)

完全有能力生成任意的vararg,并且可以加泛型