跳到主要内容

一些杂乱知识的总结与比较

C++ 是谁在维护

C++ 是一种通用的编程语言,由 Bjarne Stroustrup 在 1980 年代开发。自那时以来,它已经发展成为一种广泛使用的编程语言。C++ 的维护和发展主要由 ISO C++ 委员会(也称为 WG21)负责。ISO C++ 委员会是一个国际组织,由来自世界各地的 C++ 专家组成,他们定期会面并通过讨论、审查和投票来改进和标准化 C++ 语言。

该委员会负责制定 C++ 的国际标准,确保语言的稳定性和兼容性。迄今为止,C++ 已有多个标准版本,包括 C++98、C++03、C++11、C++14、C++17 和 C++20。委员会会继续开发新的特性和功能,并将其纳入未来的 C++ 标准。

Clang / LLVM / G++ 有什么区别

Clang、LLVM 和 G++ 都与 C++ 编程语言相关,但它们扮演着不同的角色。下面是对它们的简要概述:

  • Clang:Clang 是一个 C、C++、Objective-C 和 Objective-C++ 编程语言的编译器。它是 LLVM 项目的一部分,旨在提供一个 GCC(GNU 编译器套件)的替代方案。Clang 的目标是提供更好的性能、更快的编译时间、更友好的错误和警告信息以及更严格的源代码兼容性。Clang 通常与 LLVM 后端一起使用,但也可以与其他后端(如 GCC)一起使用。
  • LLVM:LLVM(Low-Level Virtual Machine)是一个编译器基础设施项目,为各种编程语言提供一套模块化和可重用的编译器和工具链技术。LLVM 包括许多不同的子项目,如编译器前端(如 Clang)、中间表示(IR)、优化器和代码生成器。LLVM 提供了一种通用的中间表示(LLVM IR),使其能够用于多种编程语言,并为各种硬件平台提供优化和代码生成支持。
  • G++:G++ 是 GNU 编译器套件(GNU Compiler Collection,简称 GCC)中的 C++ 编译器。GCC 最初是一个 C 语言编译器,后来发展成为一个支持多种编程语言的编译器套件,包括 C++、Objective-C、Fortran、Ada、D、Rust 等。G++ 是一个成熟的编译器,广泛应用于许多操作系统(尤其是基于 Linux 的系统)和硬件平台上。

总之,Clang 是一个编译器前端,用于将 C++ 源代码转换成中间表示;LLVM 是一个编译器基础设施项目,提供编译器前端、优化器和代码生成器等组件;而 G++ 则是 GNU 编译器套件中的 C++ 编译器。这些工具都有各自的特点和优势,开发者可以根据项目需求和个人喜好选择使用。

C++ 有官方网站吗

C++ 并没有一个官方的中心化网站,但有一些非常重要和有价值的资源,它们可以帮助您学习和了解 C++ 语言以及其生态系统。以下是一些建议的资源:

  • ISO C++ 委员会官方网站( https://isocpp.org/ ):这个网站是一个重要的资源,提供有关 C++ 标准化进程、新闻、博客、论文和事件的信息。您还可以找到有关 C++ 标准的详细文档。
  • C++ 参考( https://en.cppreference.com/ ):这是一个广泛使用的在线 C++ 参考资料,提供了对 C++ 语言特性、标准库和语法的详细描述。这个网站对于学习 C++ 语言和库的细节非常有用。
  • Cplusplus.com( https://www.cplusplus.com/ ):这个网站提供了丰富的 C++ 教程、参考和文章,可以帮助初学者和有经验的开发者学习和了解 C++ 语言和库。

虽然 C++ 没有官方的中心化网站,但通过访问上述资源,您可以获得大量关于 C++ 的知识和信息。此外,还有许多其他在线论坛、博客和教程,可以帮助您学习和了解 C++ 编程。

C++ 开源吗 盈利吗

C++ 本身是一种编程语言,而不是一个具体的实现。C++ 的标准和规范由 ISO C++ 委员会制定,但这个标准本身不是开源的。然而,有许多 C++ 编译器和库的实现是开源的,这意味着您可以查看和修改它们的源代码。例如,GCC(GNU Compiler Collection)和 Clang/LLVM 是两个广泛使用的、基于开源许可证的 C++ 编译器。

关于 C++ 是否盈利,这个问题应该从不同的角度来看。C++ 语言本身不会产生盈利,但许多公司和组织都在使用 C++ 开发商业软件,这些软件可以产生收入。此外,有些公司为 C++ 开发者提供支持、培训和工具,这些服务也可能产生收入。

总的来说,C++ 作为一种编程语言,其价值主要在于它所创建的软件和应用程序,而不是直接产生盈利。但是,通过使用 C++ 开发商业软件和提供相关服务,许多公司和开发者可以实现盈利。

标准不开源怎么实现的编译器

虽然 C++ 标准本身不是开源的,但它是公开可用的。ISO C++ 委员会发布了一系列的文档,详细描述了 C++ 语言和库的规范。这些文档可以免费在线获取,允许开发者查看和理解 C++ 的规范。因此,实现一个 C++ 编译器不需要访问源代码,而是需要遵循这些公开的规范和文档。

基于这些规范,许多开发团队和组织创建了各种 C++ 编译器和工具,其中一些是开源的。例如,GCC(GNU Compiler Collection)和 Clang/LLVM 是两个广泛使用的、基于开源许可证的 C++ 编译器。这些编译器的开发者阅读了公开的 C++ 规范,然后实现了一个遵循这些规范的编译器。这些编译器可以解析、编译和执行 C++ 源代码,从而使开发者能够使用 C++ 编程语言构建应用程序。

简而言之,虽然 C++ 标准本身不是开源的,但公开的规范允许开发者实现遵循这些规范的编译器。许多这样的编译器是开源的,允许开发者查看和修改它们的源代码。

LLVM Core 是什么

LLVM Core,通常简称为 LLVM,是一个编译器基础设施项目,提供一套模块化、可重用的编译器和工具链技术。LLVM 是 Low-Level Virtual Machine(低级虚拟机)的缩写,尽管如今它已经不仅仅局限于虚拟机概念。LLVM 的核心组件包括一系列库,这些库可以用于构建编译器、静态分析器、代码生成器、链接器等各种工具。

LLVM Core 的主要组件有:

  • LLVM IR(中间表示):LLVM 提供了一种语言无关的、类型化的、低级别的中间表示。这种中间表示用于在编译器优化和代码生成阶段传递程序信息。它允许 LLVM 支持各种编程语言,并为多个硬件平台提供优化和代码生成。
  • 优化器:LLVM 包含一套丰富的编译器优化算法,这些算法作用于 LLVM IR。优化器可以执行各种传统的编译器优化,如常量传播、死代码消除、循环不变量代码移动等,以生成更高效的目标代码。
  • 代码生成器:LLVM 提供了一套代码生成器,用于将 LLVM IR 转换为多种硬件平台和指令集体系结构(ISA)的目标代码。这使得 LLVM 可以用于为各种处理器和设备生成高效的机器代码。

LLVM Core 旨在提供一套高度模块化、可扩展和可重用的编译器组件,使得开发者可以构建自定义的编译器和工具链。这使得 LLVM 成为了许多编程语言编译器(如 Clang、Rust、Julia、Swift 等)的基础设施。

LLVM 的前端有什么,后端有什么

LLVM 提供了一套模块化的编译器基础设施,这意味着它可以与各种编程语言的前端和多种硬件平台的后端一起使用。以下是 LLVM 的一些常见前端和后端组件:

前端:

  • Clang:Clang 是一个用于 C、C++、Objective-C 和 Objective-C++ 的编译器前端。它负责将源代码解析成 LLVM IR(中间表示),以便进行优化和代码生成。
  • Swift:Swift 编译器是为 Apple 开发的 Swift 语言创建的编译器前端。它将 Swift 代码转换为 LLVM IR,然后利用 LLVM 的优化器和代码生成器。
  • Rust:Rust 编程语言的官方编译器(rustc)也使用 LLVM 作为其后端。它将 Rust 源代码转换为 LLVM IR,进而生成目标代码。
  • Julia:Julia 编程语言使用 LLVM 作为其 JIT(即时编译)和 AOT(预先编译)编译器的后端,将 Julia 源代码转换为 LLVM IR。

这些只是使用 LLVM 作为后端的许多编程语言中的一部分。还有其他许多语言和项目使用 LLVM 作为其编译器基础设施。

后端:

LLVM 支持许多不同的处理器架构和指令集。以下是一些常见的 LLVM 后端:

  • X86/X86-64:用于 Intel 和 AMD 的通用处理器。
  • ARM:用于许多嵌入式系统和移动设备的处理器。
  • AArch64:用于 ARMv8 架构的 64 位处理器。
  • PowerPC:用于 IBM 和其他制造商的 PowerPC 架构处理器。
  • MIPS:用于 MIPS 架构的处理器。
  • WebAssembly:用于在浏览器环境中运行的虚拟指令集体系结构。

这些只是 LLVM 支持的一部分后端。LLVM 项目不断发展,支持更多的处理器架构和指令集。

通过与各种前端和后端组件的结合,LLVM 为编译器开发者提供了一套灵活、模块化的编译器基础设施。这使得 LLVM 成为了构建许多编程语言编译器和工具链的理想选择。

libc++ 是什么,为什么在 Windows 上不能用

libc++ 是一个 C++ 标准库实现,它是 LLVM 项目的一部分。C++ 标准库包含了 C++ 语言所需的一些基本功能,如输入/输出操作、字符串处理、容器和算法等。libc++ 的设计目标是提供一个高度模块化、高效且易于扩展的实现,以支持 C++11 及以后的标准。

在 Windows 上,C++ 标准库的默认实现是 Microsoft Visual C++ 运行时库(MSVCRT)。然而,libc++ 本身并非不能在 Windows 上使用,但由于它没有得到与 MSVCRT 相同程度的集成和支持,因此在 Windows 上使用 libc++ 可能会面临一些挑战。

libc++ 可以在 Windows 上与 Clang 编译器一起使用,但您可能需要进行一些配置。在 Windows 上使用 libc++ 的一个方法是通过安装 LLVM 工具链和使用 Clang 编译器。然后,您需要告诉编译器使用 libc++ 而不是默认的 MSVCRT。这可以通过在编译命令行中添加以下参数来实现:

-stdlib=libc++

值得注意的是,在 Windows 上使用 libc++ 可能导致与其他 Windows 特定库和 API 的兼容性问题,因为它们可能依赖于 MSVCRT。在这种情况下,您需要仔细评估是否有必要在 Windows 上使用 libc++,或者坚持使用默认的 MSVCRT。

总之,虽然 libc++ 本身可以在 Windows 上使用,但由于它在 Windows 上的集成程度较低,可能会遇到一些兼容性和配置问题。在 Windows 上使用 libc++ 的情况相对少见,大多数情况下,开发者会选择使用默认的 MSVCRT。

为什么不对现有的实现(例如 libstdc++)进行补充而新开一个 libc++

libc++官方文档里有这么一段话

After its initial introduction, many people have asked "why start a new library instead of contributing to an existing library?" (like Apache’s libstdcxx, GNU’s libstdc++, STLport, etc). There are many contributing reasons, but some of the major ones are:

From years of experience (including having implemented the standard library before), we’ve learned many things about implementing the standard containers which require ABI breakage and fundamental changes to how they are implemented. For example, it is generally accepted that building std::string using the "short string optimization" instead of using Copy On Write (COW) is a superior approach for multicore machines (particularly in C++11, which has rvalue references). Breaking ABI compatibility with old versions of the library was determined to be critical to achieving the performance goals of libc++.
Mainline libstdc++ has switched to GPL3, a license which the developers of libc++ cannot use. libstdc++ 4.2 (the last GPL2 version) could be independently extended to support C++11, but this would be a fork of the codebase (which is often seen as worse for a project than starting a new independent one). Another problem with libstdc++ is that it is tightly integrated with G++ development, tending to be tied fairly closely to the matching version of G++.
STLport and the Apache libstdcxx library are two other popular candidates, but both lack C++11 support. Our experience (and the experience of libstdc++ developers) is that adding support for C++11 (in particular rvalue references and move-only types) requires changes to almost every class and function, essentially amounting to a rewrite. Faced with a rewrite, we decided to start from scratch and evaluate every design decision from first principles based on experience. Further, both projects are apparently abandoned: STLport 5.2.1 was released in Oct’08, and STDCXX 4.2.1 in May’08.

在最初的介绍之后,许多人问:"为什么要开始一个新库,而不是为现有库做贡献?"(比如 Apache 的 libstdcxx、GNU 的 libstdc++、STLport 等)。有很多原因,但主要原因有以下几点:

多年的经验(包括以前实现过标准库)让我们了解到关于实现标准容器的许多事情,这些事情需要破坏 ABI(应用程序二进制接口)并对它们的实现进行根本性改变。例如,普遍认为,使用"短字符串优化"而不是使用写时复制(COW)来构建 std::string 对于多核机器来说是一种更好的方法(特别是在 C++11 中,它具有右值引用)。与旧版本的库破坏 ABI 兼容性被认为对实现 libc++ 的性能目标至关重要。 主线 libstdc++ 已经切换到 GPL3,这是 libc++ 开发者无法使用的许可证。libstdc++ 4.2(最后一个 GPL2 版本)可以独立扩展以支持 C++11,但这将是代码库的一个分支(这通常被认为对项目比开始一个新的独立项目更糟糕)。libstdc++ 的另一个问题是它与 G++ 开发紧密集成,往往与相应版本的 G++ 关系密切。 STLport 和 Apache libstdcxx 库是另外两个受欢迎的候选者,但它们都缺乏 C++11 支持。我们的经验(以及 libstdc++ 开发者的经验)是,添加对 C++11 的支持(特别是右值引用和移动类型)需要对几乎每个类和函数进行更改,实质上相当于一次重写。面对重写,我们决定从头开始,并根据经验基于第一原则评估每个设计决策。此外,这两个项目似乎都已经被放弃:STLport 5.2.1 发布于 2008 年 10 月,STDCXX 4.2.1 发布于 2008 年 5 月。

libstdc++ 和 libc++ 有什么区别

libstdc++ 和 libc++ 都是 C++ 标准库的实现,但它们在许多方面有所不同。以下是它们之间的一些主要区别:

  • 项目来源与维护者:libstdc++ 是 GNU 项目的一部分,由 GCC(GNU 编译器集合)团队维护。它通常与 GCC 的 C++ 编译器(g++)一起使用。相反,libc++ 是 LLVM 项目的一部分,由 LLVM 团队维护,通常与 Clang 编译器一起使用。
  • 许可证:libstdc++ 采用了 GPL3 许可证,这是一种相对更严格的开源许可证。libc++ 使用更宽松的 University of Illinois/NCSA 开源许可证,允许在更多场景下使用该库,如在专有软件中。
  • 对 C++11 及更高版本的支持:libc++ 从一开始就专注于支持 C++11 及更新的标准,因此对新的 C++ 特性的支持可能会更快。虽然 libstdc++ 也支持现代 C++ 标准,但在某些情况下,它可能会略落后于 libc++。
  • 性能和实现差异:libc++ 和 libstdc++ 在某些实现细节上有所不同,这可能会导致性能差异。例如,libc++ 的 std::string 实现使用短字符串优化(Short String Optimization),而非写时复制(Copy-On-Write),这在多核机器上可能带来更好的性能。然而,具体性能差异可能因情况而异。
  • 平台支持:尽管 libstdc++ 和 libc++ 都支持各种操作系统,但它们在不同平台上的集成程度可能有所不同。例如,在 Linux 系统上,libstdc++ 是默认的 C++ 标准库实现;而在 macOS 和部分 BSD 系统上,libc++ 是默认实现。
  • ABI(应用程序二进制接口)兼容性:libc++ 和 libstdc++ 在 ABI 方面有所不同,这意味着使用这些库的二进制文件之间可能存在兼容性问题。因此,在选择一个库作为项目的基础时,需要考虑 ABI 兼容性问题。

总之,libstdc++ 和 libc++ 都是 C++ 标准库的实现,它们之间的区别主要在于项目来源、许可证、实现细节和平台支持等方面。在选择使用哪个库时,应根据项目需求和目标平台进行权衡。

GNU 是什么

GNU(GNU's Not Unix)是一个自由软件项目,旨在创建一个完全自由的类 Unix 操作系统。该项目由 Richard Stallman 于 1983 年发起,随后于 1985 年正式启动。GNU 的目标是为用户提供一个不受专有软件限制的操作系统,用户可以自由地使用、共享、研究和修改软件。

GNU 项目包括了一系列用于构建操作系统的基本工具、实用程序和库,如编译器(GCC)、调试器(GDB)、Shell(如 Bash)、文本编辑器(如 Emacs)以及许多核心库(如 glibc)等。尽管 GNU 项目开发了大量的基本组件,但由于缺少内核,它无法单独作为一个完整的操作系统使用。

为弥补这一缺陷,GNU 项目与 Linux 内核相结合,创建了 GNU/Linux 操作系统。GNU/Linux 是一个完全自由且开放源代码的操作系统,结合了 GNU 提供的基本工具和实用程序以及 Linux 内核。今天,GNU/Linux 已经演变成许多流行的发行版,如 Debian、Ubuntu、Fedora 和 Arch Linux 等。

GNU 项目与自由软件运动密切相关。自由软件运动鼓励创建和使用自由软件,以确保用户在计算机和软件方面有更多的自由。为了明确这种自由的程度,GNU 项目发布了一系列许可证,如通用公共许可证(GPL)、较宽松的通用公共许可证(LGPL)以及 GNU 自由文档许可证(GFDL)。这些许可证旨在确保软件的自由传播和改进,同时防止它们被专有化。

GPL2 和 GPL3 有什么区别

GNU 通用公共许可证(GPL)是一种自由软件许可证,旨在确保软件的自由传播和改进。GPL2 和 GPL3 是 GPL 的两个主要版本,它们之间有一些重要的区别。以下是它们之间的一些主要区别:

  • 专利授权:GPL3 引入了明确的专利授权条款,以防止使用 GPL 代码的公司通过专利权限制其他人使用 GPL 软件。在 GPL3 许可下,分发软件的人必须为收件人提供专利许可,以便他们可以合法地使用、修改和再分发软件。相比之下,GPL2 对专利问题的处理较为模糊。
  • "附加限制"的处理:GPL3 允许从其他兼容许可证的软件中导入额外的许可条款,只要这些条款不会对 GPL3 带来实质性的限制。这使得 GPL3 与其他许可证的互操作性得到了改善。而 GPL2 对此没有明确规定。
  • DRM 和"提高用户自由":GPL3 包含了反对数字权利管理(DRM)的条款,防止 GPL 软件被用于实施 DRM 限制。如果 GPL3 软件被用于 DRM 系统,该系统必须提供用户绕过 DRM 的方法。GPL2 中没有这样的条款。
  • 与 Affero GPL 的兼容性:GPL3 使得与 Affero GPL(一种为网络服务设计的自由软件许可证)的互操作性成为可能。这意味着在 Affero GPL 许可下的软件可以与 GPL3 许可下的软件结合。GPL2 与 Affero GPL 不兼容。
  • 终止条款:GPL2 在许可证被违反时立即终止,而 GPL3 提供了一个 30 天的宽限期来纠正违规行为。这使得使用 GPL3 软件的开发者在意外违反许可证时有机会纠正错误。
  • 国际化:GPL3 更加关注国际化问题,为此对许可证中的一些法律术语进行了澄清,使其在不同国家的法律体系下更容易适用。GPL2 在这方面较为简单。

尽管 GPL2 和 GPL3 在许多方面有所不同,但它们的核心目标是相同的:确保软件的自由传播和改进,同时保护开发者和用户的权益。在选择许可证时,应根据项目需求和目标受众来权衡这些区别。

Linux / Mac / Windows下分别什么 C++ 编译器是主流的

在 Linux、macOS 和 Windows 系统中,有几种主流的 C++ 编译器。以下是针对每个操作系统的主流编译器:

  • Linux
    • GCC(GNU Compiler Collection):GCC 是 Linux 下最常用且默认的 C++ 编译器。它支持多种编程语言,包括 C++。在 Linux 下,GCC 的 C++ 编译器通常称为 g++。
    • Clang:Clang 是 LLVM 项目的一部分,是一个越来越流行的 C++ 编译器。它提供了与 GCC 类似的功能,但以更好的错误和警告信息、更快的编译时间和对 C++ 标准更新的快速支持而闻名。
  • macOS
    • Clang:在 macOS 系统上,Clang 是默认的 C++ 编译器,它与 Xcode 集成在一起。与 Linux 上的 Clang 类似,它提供了高质量的错误和警告信息、较快的编译时间以及对 C++ 标准更新的快速支持。
  • Windows
    • Microsoft Visual C++(MSVC):MSVC 是 Windows 平台上的主流 C++ 编译器,与 Visual Studio 集成在一起。它提供了强大的功能和工具集,但可能与 GCC 和 Clang 在某些语言特性支持和实现上有所不同。
    • MinGW(Minimalist GNU for Windows):MinGW 是 Windows 下的 GCC 移植版本,使得 Windows 用户能够使用与 Linux 类似的 GCC 编译器。
    • Clang:Clang 也可以在 Windows 上使用,并与 Visual Studio 集成。在某些情况下,开发者可能会选择 Clang 作为其 C++ 编译器,以获得更好的错误和警告信息、更快的编译时间以及对 C++ 标准更新的快速支持。 不同的项目和需求可能会影响到选择哪个编译器。在许多情况下,开发者可以在同一个项目中使用多个编译器,以确保代码在不同平台和编译器上的兼容性。

STL 是什么

STL(Standard Template Library,标准模板库)是 C++ 标准库的一个重要组成部分,它提供了一组通用的模板类和函数,用于实现各种常见的数据结构和算法。STL 的设计目标是高度模块化、可扩展性以及与编译器无关的高效性能。

STL 主要包含以下几类组件:

  • 容器(Containers):容器是用于存储数据的对象,如向量(vector)、链表(list)、队列(queue)、栈(stack)、集合(set)、映射(map)等。这些容器在内部实现了各种数据结构,以便于存储和管理数据。
  • 迭代器(Iterators):迭代器是一种类似于指针的对象,可以在容器中遍历元素。迭代器提供了一种统一的访问容器元素的方法,无论底层数据结构如何。迭代器与 STL 的容器和算法紧密集成,使得编写通用和可重用的代码变得更容易。
  • 算法(Algorithms):STL 提供了许多通用算法,如排序、查找、复制、替换等。这些算法可以在不同类型的容器和数据结构上使用,使得编写高效且可移植的代码变得简单。
  • 函数对象(Function Objects):函数对象(又称仿函数,functor)是一种具有 operator() 的类或结构体对象。在 STL 中,函数对象可用作算法的自定义操作,以实现用户自定义的比较、操作或计算。函数对象的一个优点是它们可以包含状态,这使得它们比普通函数更灵活。
  • 适配器(Adapters):适配器是一种修改容器、迭代器或函数对象行为的工具。例如,堆栈适配器(stack adapter)可以将一个底层容器(如 vector 或 deque)转换为一个具有堆栈语义的容器。

STL 通过模板编程技术实现,使得它能够处理各种数据类型和用户自定义类型。这种泛型编程方法使得代码更加可重用和可扩展,同时保持高效的运行时性能。

statement 和 expression 有什么区别

  • 表达式(expression):表达式是一个代码片段,它会计算并产生一个值。表达式由操作数(如变量、常量或字面量)和操作符(如算术、关系或逻辑操作符)组成。表达式可以组合使用,嵌套在更大的表达式中。例如,x + 1、a * (b + c) 和 5 都是表达式。在函数式编程语言中,几乎所有的代码结构都是表达式。
  • 语句(statement):语句是一个执行某种操作的代码片段,它不返回值。语句用于表示控制流程、变量声明、赋值等操作。语句通常包含一个或多个表达式。例如,if 语句、while 循环、for 循环、变量声明和赋值语句等。在过程式和面向对象编程语言中,语句是构建程序逻辑的基本单位。

以下是表达式和语句之间的一些关键区别:

  • 表达式计算并返回一个值,而语句执行操作但不返回值。
  • 表达式可以组合成更大的表达式,而语句表示独立的操作。
  • 表达式主要用于计算值,而语句主要用于控制流程和执行操作。

在某些编程语言中(如 Python、Ruby 或 Kotlin),有些结构既可以看作是表达式又可以看作是语句。例如,在 Python 中,x = 1 是一个赋值语句,但它也是一个表达式,其值为 1。这种情况下,表达式和语句的界限可能变得模糊。然而,在其他编程语言中(如 C++ 或 Java),表达式和语句之间的界限更加明确。