(免责声明:我不是 100% 确定 codatatype 是如何工作的,特别是在不涉及终端代数时)。
考虑“类型类别”,类似于Hask,但进行了适合讨论的任何调整。在这样的类别中,据说(1)初始代数定义数据类型,(2)终端代数定义协数据类型。
我正在努力说服自己相信(2)。
考虑函子T(t) = 1 + a * t。我同意初始T代数是明确定义的并且确实定义了[a], 的列表a。根据定义,初始的T-algebra 是一个类型X和一个函数f :: 1+a*X -> X,这样对于任何其他类型Y和函数g :: 1+a*Y -> Y,都存在一个m :: X -> Y这样的函数m . f = g . T(m)(其中.表示 Haskell 中的函数组合运算符)。通过f解释为列表构造函数、g初始值和阶跃函数以及T(m)递归操作,该方程本质上断言了m给定任何初始值和 中定义的任何阶跃函数的函数的唯一存在性g,这需要一个底层的良好-fold与基础类型(. 列表)一起表现a。
例如,g …
在最新版本的 gcc 中,具有不同来源的指针可以是相等的:
// test.c
#include <stdio.h>
int a[4];
int b[4];
int main() {
puts(a+4 == b ? "equal" : "inequal");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ gcc --version
gcc (GCC) 13.2.1 20230801
$ gcc test.c && ./a.out
equal
Run Code Online (Sandbox Code Playgroud)
这种行为符合c标准吗?
该博客声称:
- 未定义的行为仅在高优化级别(例如 -O2 或 -O3)下“发生”。
- 如果我使用 -O0 之类的标志关闭优化,那么就没有 UB。
都是假的。我想知道是否有任何现实世界的展示可以证明这一点。
例如,n << 1当 时触发 UB n<0。对于以下函数:
void foo(int n) {
int t = n<<1;
if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
编译器可以谨慎地编译它:
void foo(int n) {
int t = n>=0 ? (n*2) : error("lshift negative int");
if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
或通常:
void foo(int n) {
int t = n*2;
if (n>=0)
nuke();
}
Run Code Online (Sandbox Code Playgroud)
或者积极优化它:
void foo(int n) {
// unused
// int t = n<<1;
// always true, otherwise …Run Code Online (Sandbox Code Playgroud)