如果我排除库和编译器扩展,C 中还剩下什么?
What remains in C if I exclude libraries and compiler extensions?
想象一下这样一种情况,您不能或不想使用编译器作为 "standard" 提供的任何库,也不想使用任何外部库。您甚至不能使用编译器扩展(例如 gcc extensions)。
如果把 C 语言中很多人理所当然使用的东西去掉,剩下的部分是什么?
以这种方式,开箱即用的任何大型 C 编译器(不仅是 ANSI C)支持的每个可调用函数的列表可能会令人满意,因为它至少大致显示了使用- 语言大小写。
首先我想到了 sizeof()
和 printf()
(这些已经在评论中阐明了 - operator + stdio
),所以......剩下的是什么? In-line assembly 似乎也是一个扩展,所以如果我是对的,那么几乎连 使用 与 C 程序集的选项都被剥夺了。
可能在代码方面它更容易理解。想象一下仅使用例如编译的代码gcc main.c
(允许输出标志)没有 #include
,也没有 extern
.
int main() {
// replace_me
return 0;
}
除了 "boring" 键入数学和从一个类型转换到另一个类型之外,我还能调用什么来实际做其他事情?
请注意,switch
、goto
、if
、循环和其他不执行任何操作且只允许重复一段代码的构造不是我要找的东西(如果不是很明显的话)。
(希望编辑澄清了我实际上在问的 wtf,但 Matteo 的回答几乎做到了。)
如果删除所有库,本质上您将拥有类似于 C 的 独立 实现的东西(它仍然必须提供一些库 - 例如,string.h,但那是没有什么是你不能用可移植的 C 轻松实现的),这就是你在对微控制器和其他没有现成操作系统的计算机进行编程时通常开始的东西——也是操作系统编写者在编译他们的操作系统时通常使用的东西操作系统。
除了"raw"计算之外,你通常有两种做事的方法:
- 汇编块(在这里你可以做任何底层机器可以做的事);
- 内存映射 IO(您将
volatile
指针设置为某个硬件相关位置并从中设置 read/write;这会影响硬件)。
这就是构建任何东西所需要的全部 - 毕竟,无论如何,这一切都归结为这些东西,常规托管实现的 C 库通常是用 C 本身编写的,一些程序集用于速度或与操作系统通信1(通常系统调用是通过某种中断调用的)。
再说一次,没有什么是您自己无法实现的。但是拥有标准库的意义在于既可以避免不断地重新发明轮子,又可以拥有一组 可移植 的函数,让您不必在了解每个目标的细节后重写所有内容平台。
- 而主流操作系统,反过来,一般也是用C和汇编混合编写的。
我觉得你还没有真正了解情况。
您不需要 header 来调用 C 中的函数。您可以使用未经检查的参数进行调用 - 这是一个糟糕的想法和过时的功能,但仍受支持。如果编译器默认 link 是一个库,而不是仅当您明确告诉它时,这只是编译器中 "link libc" 的一个小切换。臭名昭著的 Unix 编译器需要被告知 link 数学库,默认情况下它没有被 link 编辑,因为一些非常早期的程序不使用浮点数。
公平地说,如今一些标准库函数(例如 memcpy)趋于 special-cased,因为它们有助于内联和优化。
标准库已记录并通常可用,但实际上出于安全原因已被 Microsoft 弃用。您可以仅使用 stdlib 函数轻松编写几乎任何函数,您不能做的是花哨的 IO。
C 本身没有 "built-in" 函数。编译器实现可能包含编译器直接实现的“intrinsic”函数,无需提供外部库,尽管内部函数仍需要原型声明,因此您通常仍会包含此类声明的头文件。
C 是一种系统级语言,具有最少的 运行 时间和启动要求。因为它可以直接访问内存和内存映射 I/O ,所以它几乎没有什么不能做的(它不能做的是你使用汇编、内联汇编或内在函数的事情)。例如,很多你想知道没有它能做什么的库代码是用 C 编写的。然而,当 运行ning 在 OS 环境中时(使用 C 作为应用程序级而不是系统级语言),你实际上不能以这种方式使用 C - OS 可以控制诸如 I/O 和内存管理之类的东西,在现代系统中通常会阻止对此类资源的无中介访问。当然 OS 本身很可能主要是用 C (and/or C++) 编写的。
在没有 OS 的独立裸机环境中,C 通常在 bootstrap 初始化硬件和建立应用程序执行环境的过程中很早就使用。事实上,在 ARM Cortex-M 处理器上,可以从复位直接启动到 C 代码,因为硬件在启动时从向量 table 加载初始堆栈指针和起始地址;这对于 运行 不依赖于库或静态数据初始化的 C 代码来说已经足够了——但是这种初始化可以在调用 main()
之前用 C 语言编写。
请注意 sizeof
不是一个函数,它是一个 operator。
想象一下这样一种情况,您不能或不想使用编译器作为 "standard" 提供的任何库,也不想使用任何外部库。您甚至不能使用编译器扩展(例如 gcc extensions)。
如果把 C 语言中很多人理所当然使用的东西去掉,剩下的部分是什么?
以这种方式,开箱即用的任何大型 C 编译器(不仅是 ANSI C)支持的每个可调用函数的列表可能会令人满意,因为它至少大致显示了使用- 语言大小写。
首先我想到了 sizeof()
和 printf()
(这些已经在评论中阐明了 - operator + stdio
),所以......剩下的是什么? In-line assembly 似乎也是一个扩展,所以如果我是对的,那么几乎连 使用 与 C 程序集的选项都被剥夺了。
可能在代码方面它更容易理解。想象一下仅使用例如编译的代码gcc main.c
(允许输出标志)没有 #include
,也没有 extern
.
int main() {
// replace_me
return 0;
}
除了 "boring" 键入数学和从一个类型转换到另一个类型之外,我还能调用什么来实际做其他事情?
请注意,switch
、goto
、if
、循环和其他不执行任何操作且只允许重复一段代码的构造不是我要找的东西(如果不是很明显的话)。
(希望编辑澄清了我实际上在问的 wtf,但 Matteo 的回答几乎做到了。)
如果删除所有库,本质上您将拥有类似于 C 的 独立 实现的东西(它仍然必须提供一些库 - 例如,string.h,但那是没有什么是你不能用可移植的 C 轻松实现的),这就是你在对微控制器和其他没有现成操作系统的计算机进行编程时通常开始的东西——也是操作系统编写者在编译他们的操作系统时通常使用的东西操作系统。
除了"raw"计算之外,你通常有两种做事的方法:
- 汇编块(在这里你可以做任何底层机器可以做的事);
- 内存映射 IO(您将
volatile
指针设置为某个硬件相关位置并从中设置 read/write;这会影响硬件)。
这就是构建任何东西所需要的全部 - 毕竟,无论如何,这一切都归结为这些东西,常规托管实现的 C 库通常是用 C 本身编写的,一些程序集用于速度或与操作系统通信1(通常系统调用是通过某种中断调用的)。
再说一次,没有什么是您自己无法实现的。但是拥有标准库的意义在于既可以避免不断地重新发明轮子,又可以拥有一组 可移植 的函数,让您不必在了解每个目标的细节后重写所有内容平台。
- 而主流操作系统,反过来,一般也是用C和汇编混合编写的。
我觉得你还没有真正了解情况。
您不需要 header 来调用 C 中的函数。您可以使用未经检查的参数进行调用 - 这是一个糟糕的想法和过时的功能,但仍受支持。如果编译器默认 link 是一个库,而不是仅当您明确告诉它时,这只是编译器中 "link libc" 的一个小切换。臭名昭著的 Unix 编译器需要被告知 link 数学库,默认情况下它没有被 link 编辑,因为一些非常早期的程序不使用浮点数。
公平地说,如今一些标准库函数(例如 memcpy)趋于 special-cased,因为它们有助于内联和优化。
标准库已记录并通常可用,但实际上出于安全原因已被 Microsoft 弃用。您可以仅使用 stdlib 函数轻松编写几乎任何函数,您不能做的是花哨的 IO。
C 本身没有 "built-in" 函数。编译器实现可能包含编译器直接实现的“intrinsic”函数,无需提供外部库,尽管内部函数仍需要原型声明,因此您通常仍会包含此类声明的头文件。
C 是一种系统级语言,具有最少的 运行 时间和启动要求。因为它可以直接访问内存和内存映射 I/O ,所以它几乎没有什么不能做的(它不能做的是你使用汇编、内联汇编或内在函数的事情)。例如,很多你想知道没有它能做什么的库代码是用 C 编写的。然而,当 运行ning 在 OS 环境中时(使用 C 作为应用程序级而不是系统级语言),你实际上不能以这种方式使用 C - OS 可以控制诸如 I/O 和内存管理之类的东西,在现代系统中通常会阻止对此类资源的无中介访问。当然 OS 本身很可能主要是用 C (and/or C++) 编写的。
在没有 OS 的独立裸机环境中,C 通常在 bootstrap 初始化硬件和建立应用程序执行环境的过程中很早就使用。事实上,在 ARM Cortex-M 处理器上,可以从复位直接启动到 C 代码,因为硬件在启动时从向量 table 加载初始堆栈指针和起始地址;这对于 运行 不依赖于库或静态数据初始化的 C 代码来说已经足够了——但是这种初始化可以在调用 main()
之前用 C 语言编写。
请注意 sizeof
不是一个函数,它是一个 operator。