Tiếng leng keng
Tôi chỉ gặp phải lỗi thú vị này.
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
std::stringstream prog;
constexpr unsigned c_strlen( char const* str, unsigned count = 0 )
{
return ('\0' == str[0]) ? count : c_strlen(str+1, count+1);
}
template < char t_c, char... tt_c >
struct rec_eval
{
static void eval()
{
rec_eval<t_c>::eval();
rec_eval < tt_c... > :: eval ();
}
};
template < char t_c >
struct rec_eval < t_c >
{
static void eval() {
switch(t_c) {
case '+':
prog<<"++t[i];";
break;
case '-':
prog<<"--t[i];";
break;
case '>':
prog<<"++i;";
break;
case '<':
prog<<"--i;";
break;
case '[':
prog<<"while(t[i]){";
break;
case ']':
prog<<"}";
break;
case '.':
prog<<"putc(t[i],stdout);";
break;
case ',':
prog<<"t[i]=getchar();";
break;
}
}
};
template < char... tt_c >
struct exploded_string
{
static void eval()
{
rec_eval < tt_c... > :: eval();
}
};
template < typename T_StrProvider, unsigned t_len, char... tt_c >
struct explode_impl
{
using result =
typename explode_impl < T_StrProvider, t_len-1,
T_StrProvider::str()[t_len-1],
tt_c... > :: result;
};
template < typename T_StrProvider, char... tt_c >
struct explode_impl < T_StrProvider, 0, tt_c... >
{
using result = exploded_string < tt_c... >;
};
template < typename T_StrProvider >
using explode =
typename explode_impl < T_StrProvider,
c_strlen(T_StrProvider::str()) > :: result;
int main(int argc, char** argv)
{
if(argc < 2) return 1;
prog << "#include <stdio.h>\n#include <stdlib.h>\nint main(){unsigned char* t=calloc(";
prog << (1 << sizeof(unsigned short));
prog << ",sizeof(unsigned short));unsigned short i=0;";
struct my_str_provider
{
constexpr static char const* str() { return "++++[>+++++<-]>+++[[>+>+<<-]>++++++[<+>-]+++++++++[<++++++++++>-]>[<+>-]<-]+++>+++++++++[<+++++++++>-]>++++++[<++++++++>-]<--[>+>+<<-]>>[<<+>>-]<-->>++++[<++++++++>-]++++++++++>+++++++++[>+++++++++++<-]>[[>+>+>+<<<-]>[<+>-]>>[[>+>+<<-]>>[<<+>>-]<[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<]<<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]>[<++++++[>++++++++<-]>.[-]]<<<<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.[>]>[>+>+<<-]>[<+>-]>[-[[-]+++++++++[<+++++++++++++>-]<--.[-]>]]<<<<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<.[<]>>>>>>>>>.>.[>]<<.[<]>>>>.>>>>>>>>>>>>.>>>.[>]<<.[<]>.[>]<<<<<<.<<<<<<<<<<<..[>]<<<.>.[>]>[>+>+>+<<<-]>[<+>-]>>[[>+>+<<-]>>[<<+>>-]<[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<]<<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]>[<++++++[>++++++++<-]>.[-]]<<<<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.[>]>[>+>+<<-]>[<+>-]>[-[[-]+++++++++[<+++++++++++++>-]<--.[-]>]]<<<<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<<<.>>>.<<<<.<.<<<<<<<<<<.>>>>>>.[>]<<.[<]>>>>>>>>>.>.>>>>>>>>>.[>]<<.<<<<<<<.[<]>>>>>>>>>.[<]>.>>>>>>>>>.[>]<<.<<<<.<<<<<<<<<<<<<.[>]<<<<<<<<<.[>]<<.[<]>>>>>>>>.[>]<<<<<<.[<]>>>>>..[>]<<.<<<<<<<<<<<<.[<]>>>>.[>]<<.<<<<.[<]>>>>>>.>>>.<<<<<<.>>>>>>>.>>>>>>>>>>.[>]<<<.>.>>>-[>+>+>+<<<-]>[<+>-]>>[[>+>+<<-]>>[<<+>>-]<[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<->-[<<<+>---------->->[-]]]]]]]]]]]<]<<[>>++++++++++++[<++++<++++>>-]<<[.[-]>]<<]>[<++++++[>++++++++<-]>.[-]]<<[>+>+<<-]>[<+>-]+>[<->[-]]<[-<<<[<]>>>>>>>>>>.<.[>]<<.[<]>>>>>>>>>>>.<<.<<<.[>]<<<<<<<<<<.[>]>>]<<<<.<<<<<.[<]>>>>>>>>>.<<<<<..>>>>>>>>.>>>>>>>.[>]>[>+>+<<-]>[<+>-]+>[<->-[<+>[-]]]<[++++++++[>+++++++++++++<-]>--.[-]<]<<<<.[<]>>>>>>>>>.>>>>>>>>>.[>]<<.<<<<<.<<<..[<]>>>>>>.[>]<<.[<]>>>>>>>>>.>.[>]<<.[<]>>>>.>>>>>>>>>>>>.>>>.[>]<<.[<]>.[>]<<<<<<.<<<<<<<<<<<..[>]<<<<.>>>..>>]"; }
};
auto my_str = explode < my_str_provider >{};
my_str.eval();
prog << "}";
std::ofstream ofs(argv[1]);
if(!ofs) return 2;
ofs << prog.str() << std::endl;
ofs.close();
return 0;
}
Mục tiêu là dịch Brainfuck sang C, sử dụng lập trình meta mẫu để thực hiện hầu hết công việc. Mã này hoạt động cho các chương trình Brainfuck nhỏ hơn, như Hello World, nhưng khi tôi cố chạy nó với 99 Chai ...
$ clang++ -std=c++11 -fconstexpr-depth=1000 bf_static.cpp
clang: error: unable to execute command: Segmentation fault (core dumped)
clang: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 3.5.2 (tags/RELEASE_352/final)
Target: i386-pc-windows-cygnus
Thread model: posix
clang: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang: note: diagnostic msg:
********************
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/bf_static-afa982.cpp
clang: note: diagnostic msg: /tmp/bf_static-afa982.sh
clang: note: diagnostic msg:
********************
Nó sẽ biên dịch thành công trong GCC (sau khoảng 2 phút), nhưng liên kết nó gây ra một vấn đề khác ...
/usr/lib/gcc/i686-pc-cygwin/4.9.3/../../../../i686-pc-cygwin/bin/as: /tmp/cc0W7cJu.o:
section .eh_frame$_ZN8rec_eval<giant mangled name removed>: string table overflow at offset 10004228
/tmp/cc3JeiMp.s: Assembler messages:
/tmp/cc3JeiMp.s: Fatal error: can't close /tmp/cc0W7cJu.o: File too big
Úi.