当前位置: 首页 > 软件库 > 开发工具 > 编译器 >

constexpr-8cc

授权协议 MIT License
开发语言 C/C++
所属分类 开发工具、 编译器
软件类型 开源软件
地区 不详
投 递 者 方高丽
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

constexpr-8cc: Compile-time C Compiler Build Status

constexpr-8cc is a compile-time C compiler implemented as C++14 constant expressions.This enables you to compile while you compile!This project is a port of 8cc built on ELVM Infrastructure.

Constant expressions in C++ are expressions that can be evaluated at compile-time.In C++14, by relaxing constrains, constant expressions became so powerful that a C compiler can be implemented in!

In constexpr-8cc, the main routine for compilations of C programs is implemented in a C++14 constexpr function.Therefore, if you compile 8cc.cpp to a binary file by g++, compilation of a C program will be performed as a compile-time computation and the result of this C compilation will be embedded into the generated binary.In this sense, constexpr-8cc is a compile-time C compiler.

The following is the main function in 8cc.cpp.

int main() {
  // Compile-time
  constexpr buffer buf = eight_cc(); // Compile C code into ELVM IR
  constexpr unsigned int output_size = buf.size;

  static_assert(0 <= output_size && output_size < EIGHT_CC_OUTPUT_LIMIT, "8cc: Error");

  // Run-time
  for(int i = 0; i < output_size; ++i) {
    putchar(buf.b[i]);
  }
}

In this program, the return value of eight_cc is stored into the variable buf with a constexpr specifier.Thus, you will find that the compilation of a C program is done in compile-time.

Requirements

constexpr-8cc requires Linux with >g++-6.2. I confirmed ./test/hello.c can be compiled with g++-6.2, g++-8.3 and g++-9.3 at least.

  • g++-6.2 worked without any extra flag related to constexpr as there was no limitation of constant's loop counts at this version.
  • With g++-8.3, I needed to enlarge constexpr's loop count with -fconstexpr-loop-limit. The maximum number we can specify is 2**31 - 1.
  • With g++-9.3, in addition to -fconstexpr-loop-limit, enlarging -fconstexpr-ops-limit was needed.
  • There is no guarantee that it works with other versions of g++.
  • I couldn't make it work with clang++ as clang++ has more strict limitation of constexpr loop counts.

How to run

Compilation by run_8cc.py

In order to try constexpr-8cc easily, use run_8cc.py.

$ ./run_8cc.py x86 ./test/hello.c -o ./hello.exe # It takes about 3 minutes on my laptop
$ chmod +x ./hello.exe                           # 'hello.exe' is i386-linux binary
$ ./hello.exe
Hello, world!

You can change the target language of compilations like the following:

$ ./run_8cc.py py ./test/hello.c -o ./hello.py # target language is Python
$ python ./hello.py
Hello, world!

For more information about this script, type $ ./run_8cc.py -h.

Compilation by hand

If you want to compile 8cc.cpp manually, please look at config.hpp.In this file, the variable EIGHT_CC_INPUT_FILE is defined.EIGHT_CC_INPUT_FILE should be a name of a file that contains a source C program as a C++ string literal.This string will be embedded in 8cc.cpp at pre-processing-time and used as an input of the compile-time computation.

So, before compiling 8cc.cpp manually, you have to convert a raw program to a string literal like the following:

$ sed '1s/^/R"(/' ./test/hello.c | sed '$s/$/\n)"/' > ./test/hello.c.txt # Convert C to string literal
$ g++-6 ./8cc.cpp -o eir_gen.out
$ ./eir_gen.out > ./test/hello.eir       # eir_gen.out outputs ELVM IR
$ sed -i '1s/^/R"(x86/' ./test/hello.eir # Convert IR to string literal
$ sed -i '$s/$/\n)"/' ./test/hello.eir
$ g++-6 ./elc.cpp -o exe_gen.out
$ ./exe_gen.out > ./hello.exe            # exe_gen.out outputs i386-linux binary
$ chmod +x ./hello.exe
$ ./hello.exe
Hello, world!

How was constexpr-8cc generated?

When you see 8cc.hpp, you will know this program was not written by hand.Actually, I used ELVM Compiler Infrastructure to generate it.I just implemented a translator from ELVM IR to C++14 constexpr here.

Author

Keiichi Watanabe (udon.watanabe [at] gmail.com)

Links

  •   编译器将在编译过程中把用到const变量的地方都替换成对应的值,为了执行这种替换,编译器必须知道变量的初始值。如果程序包含多个文件,则那个用了const对象的文件都必须能访问到它的初始值才行。要做到这一点,就必须在每一个用到变量的文件中都有对它的定义。为了支持这一用法,同时避免对同一变量的重复定义,默认情况下,const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时,其实

  • const与constexpr c++开发中,常量属性是避免不了要接触的。如果运用不好,函数或变量的常量属性会给你造成麻烦。其中,把const和constexpr这两个关键字弄混是一大原因。(当然还有其他原因引起困惑。。)本文我们试图解决以下2个问题: const与constexpr的区别? 常函数的使用建议? 一、const与constexpr的区别 《c++ primer》中有对这个问题的详细

  • 有点难理解权且记住,使用才会体会其中真正的差别。 常量表达式的概念:在编译期就可以计算出结果的表达式。 那么为什么要用常量表达式呢,用常量表达式会有什么好处: 1.允许一些计算只在编译时进行一次,而不是每次程序运行时; 2.编译器可以进行尺度更大的优化; 3.可以用在需求编译期间常量的上下文,例如数组长度等; 使用constexpr修饰变量时: const 变量的初始化可以延迟到运行时,而 con

  • const是一种类型修饰符 定义一个变量,它的值不能被改变。比如用一个变量来表示缓冲区的大小。 const int size = 128;//const的int类型 size = 1;//const对象一旦被创建以后,其值就不能再改变 const int i = get_size();//正确,运行时初始化 const int j = 11;//正确,编译时初始化 const int k

  • title date tags categories description C++的const和constexpr 2020-04-24 13:40:22 -0700 const constexpr C/C++ 用于定义不可改变的量 const 因为const对象一旦创建后就不能改变,所以必须初始化 一般变量的定义不能使用extern关键字,而如果想在多个文件之间共享const对象,必须在变量的

  •    如果有人问在C++11引入的众多关键字中,有哪个关键字是最让你迷惑的,我会立马回答是constexpr,当这个关键字应用到对象上的时候,它其实就是一个加强版的const,但是当它应用到函数身上,它就有了不同的含义。为此很有必要去深入学习constexpr解除其迷惑,使得我们在使用它的时候是符合预期的。 ​   从概念上讲,constexpr修饰的值不仅仅是一个常量值,而且还是一个编译期(参见

  • 先看一个简单的例子: class test{ public: constexpr test(){ } constexpr int operator + (const test& rhs){ return 1; } }; int main() { test t; constexpr int b

  • constexpr函数是如何在编译期执行的?constexpr函数局部变量以及循环是如何实现?constexpr if是什么原理?或许你有不少疑惑,但目前关于constexpr编译期的资料还比较少,本文笔者将从 gcc 的源码简单分析一下,以此来抛砖引玉,让更多的人加入到对constexpr的讨论中。 我用的是最新的gcc 11源码,直接翻到gcc/gcc/cp/constexpr.cc,在这个文

  • constexpr变量 字面值类型包括算术类型、引用、指针、枚举和数据成员都是字面值类型的聚合类。 聚合类的定义:     所有成员都是public的。     没有定义任何构造函数。     没有类内初始值。     没有基类,也没有虚函数。 如: struct Data {     int ival;     string str; };     1     2     3     4 如果一

  • const 被const修饰的变量,不能对其进行赋值操作 但是,可以通过访问const对象的内存,对其进行修改 分析下面代码 int main(){ const int data = 10; int *p = const_cast<int*>(&data); *p = 20; std::cout << data << std::endl; //10

  • 引言 社区(http://purecpp.org/)里有朋友提出了编译期分割字符串的需求,大家在群里进行了热烈的讨论,也做了许多尝试,但并没有得出确定的结果。本文作者试图对C++11/14里的新关键字constexpr进行编译期计算的总结和探讨,并在最后结合constexpr给出C++在编译期分割字符串的方法。 一、编译期计算 我们先来看一段求阶乘(factorial)的算法: size_t fa

  • 书中页数:P213 代码名称:inline_shorter.cc #include <string> using std::string; #include <iostream> using std::cout; using std::endl; //inline version: find the shorter of two strings inline const string & sh

  • 1 简介 constexpr函数指的是在编译的时候就能得到其返回值的函数,也就是说编译器将constexpr函数直接转换成其返回值,因此,constexpr函数都是被隐式地定义为内联函数。使用constexpr关键字来修饰constexpr函数。 2 使用方法 有如下代码: constexpr int myFunc() {   return 1; } constexpr int i = myFun

  • c++ const 和 constexpr 知识点总结 一、const 1. const修饰变量 修饰普通变量(常量) const int a = 0; // 必须赋初始值,然后不能被重新赋值 默认情况下,const对象被设定为仅在文件内有效。如果需要多文件共享const对象,需要在const对象的声明和定义处加上extern修饰。 file1.cpp extern const int aext

  • const 和 constexpr 用法 const用法 语义 const 是一个限定符 ,用 const 定义的变量被视为常量,const 对象一旦创建其值就不能再改变。除非用于定义类成员,否则 const 创建对象是必须初始化,否则无法通过编译。默认状态下,const 对象仅在文件内有效,当多个文件中出现同名的const常量时,其实等同于在不同文件中分别定义了独立的常量。如果需要在多个文件中使

  • #1、删除QT源码头文件报错地方的constexpr #2、在项目pro文件添加DEFINES += Q_COMPILER_UNIFORM_INIT /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. **

  • 语义上: constexpr:告诉编译器我可以是编译期间可知的,尽情的优化我吧。 const:告诉程序员没人动得了我,放心的把我传出去;或者放心的把变量交给我,我啥也不动就瞅瞅。 语法上: constexpr是一种比const 更严格的束缚, 它修饰的表达式本身在编译期间可知, 并且编译器会尽可能的 evaluate at compile time. 在constexpr 出现之前, 可以在编译期

 相关资料
  • 我试图创建一个在编译时构造然后可以使用的类,当然不需要任何修改它的方法。我对和这两个关键字是新手,所以我可能没有正确使用它们。 下面是我的代码: 一旦被修复,就可以在编译时评估所有所需的计算,因此可以肯定地说,就可以执行我正在尝试的操作。方法只读取data_member而不修改它。 当我编译时,我得到: 引用到构造函数。我看到这是一个问题,但在我的情况下,我将不再修改对象。我怎么告诉编译器呢?

  • C++1z将引入“constexpr if”-一个将根据条件删除其中一个分支的if。似乎合理有用。 但是,没有constexpr关键字就不行吗?我认为在编译过程中,编译器应该知道编译时是否知道条件。如果是的话,即使是最基本的优化级别也应该移除不必要的分支。 例如(参见godbolt:https://godbolt.org/g/ipy5y5): Godbolt explorer显示,即使带有-o0的

  • 为什么 C 编译器可以将函数声明为 constexpr,而 constexpr 不能是 constexpr? 例如:http://melpon.org/wandbox/permlink/AGwniRNRbfmXfj8r 输出: 为什么此行出错:

  • 我正在努力升级一些C代码,以利用C 11中的新功能。我有一个trait类,其中有几个函数返回基本类型,大多数情况下,但并非总是返回常量表达式。我想根据函数是否为来做不同的事情。我提出了以下方法: 额外的< code>int/参数的作用是,如果SFINAE之后两个函数都可用,重载解析将选择第一个函数。 用Clang 3.2编译并运行该代码显示: 所以这似乎有效,但我想知道代码是否合法C 11。特别是

  • 我想确认这个代码是合法的(还是不合法的?)C++17。 如果用G++和MSVC编译,我不会得到错误(并得到正确的输出), 但Intel和clang给出了一个错误: 使用编译(对于MSVC)。 在godbolt和我的本地机器上尝试了最新的编译器。

  • 这段代码在g(coliru)中编译得很好,但不能在MSVC(godbolt和我的VS2017)中编译。 (6):错误C2131:表达式未计算为常量 (6):注意:失败是由读取超出其生命周期的变量 (6)引起的:注意:请参阅“this”的用法 哪一个(g或MSVC)是错误的? 这在“请参阅'这个'的用法”中是什么?? 如何在保证编译时间的同时解决它? 在我的实际情况中,是一个复杂的语句,它依赖于其他