是否有未能编译这个C编译器? [英] Is there a C compiler that fails to compile this?
问题描述
我是挂在我的探查了试图找出如何加速这是周围的日期解析瓶颈一个共同的日志分析器一段时间,我尝试过各种算法,以加快速度。
我想这是事情发展最快,我也是迄今最可读的,但可能不标准的C
这相当奏效的 GCC ,的 ICC 和我真的老和挑剔的SGI编译器。因为它是一个相当可读的优化,在这里没有它做我想要什么?
静态INT parseMonth(为const char *输入){
INT RV = -1;
INT inputInt = 0;
INT I = 0; 对于(I = 0; I&4;放大器;&放大器;输入由[i];我++){
inputInt =(inputInt&所述;&下; 8)|输入[I]
} 开关(inputInt){
案扬/':RV = 0;打破;
案二月/':RV = 1;打破;
案三月/':RV = 2;打破;
案四月/':RV = 3;打破;
案五月/':RV = 4;打破;
案军/':RV = 5;打破;
案七月/':RV = 6;打破;
案八月/':RV = 7;打破;
案月/':RV = 8;打破;
案十月/':RV = 9;打破;
案月/':RV = 10;打破;
案DEC /':RV = 11;打破;
}
返回rv;
}
的Solaris 10 - SPARC - Sun编译
测试code:
的#include<&stdio.h中GT;静态INT parseMonth(为const char *输入){
INT RV = -1;
INT inputInt = 0;
INT I = 0; 对于(I = 0; I&4;放大器;&放大器;输入由[i];我++){
inputInt =(inputInt&所述;&下; 8)|输入[I]
} 开关(inputInt){
案扬/':RV = 0;打破;
案二月/':RV = 1;打破;
案三月/':RV = 2;打破;
案四月/':RV = 3;打破;
案五月/':RV = 4;打破;
案军/':RV = 5;打破;
案七月/':RV = 6;打破;
案八月/':RV = 7;打破;
案月/':RV = 8;打破;
案十月/':RV = 9;打破;
案月/':RV = 10;打破;
案DEC /':RV = 11;打破;
} 返回rv;
}静态常量结构
{
字符*的数据;
INT结果;
} test_case [] =
{
{一月/,0},
{二月/,1},
{月/,2},
{四月/,3},
{五月/,4},
{君/,5},
{七月/,6},
{月/,7},
{月/,8},
{月/,9},
{月/,10},
{DEC /,11},
{AJ / N,-1},
};DIM的#define(X)(sizeof的(X)/ sizeof的(*(X)))INT主要(无效)
{
为size_t我;
INT结果; 对于(i = 0; I< DIM(test_case);我++)
{
结果= parseMonth(test_case [I]。数据);
如果(结果!= test_case [I]。结果)
的printf(!! FAIL !!%S(得到%d,就想%D)\\ n
test_case [I]。数据,结果,test_case [I]。结果);
}
返回(0);
}
结果(GCC 3.4.2和Sun):
$ gcc的-O xx.c -o XX
xx.c:14:14:警告:多字符字符常量
xx.c:15:14:警告:多字符字符常量
xx.c:16:14:警告:多字符字符常量
xx.c:17:14:警告:多字符字符常量
xx.c:18:14:警告:多字符字符常量
xx.c:19:14:警告:多字符字符常量
xx.c:20:14:警告:多字符字符常量
xx.c:21:14:警告:多字符字符常量
xx.c:22:14:警告:多字符字符常量
xx.c:23:14:警告:多字符字符常量
xx.c:24:14:警告:多字符字符常量
xx.c:25:14:警告:多字符字符常量
$ ./xx
$ CC -o XX xx.c
$ ./xx
! FAIL!扬/(-1了,就想0)
! FAIL!二月/(-1了,本想1)
! FAIL!三月/(-1了,就想2)
! FAIL!四月/(-1了,希望3)
! FAIL!五月/(-1了,就想4)
! FAIL!君/(-1了,本想5)
! FAIL!七月/(-1了,就想6)
! FAIL!八月/(-1了,本想7)
! FAIL!九月/(-1了,就想8)
! FAIL!十月/(-1了,就想9)
! FAIL!十一月/(-1了,本想10)
! FAIL! DEC /(-1了,本想11)
$
请注意,最后的测试案例还通过了 - 也就是说,它产生了-1
下面是一个修订后的 - 更详细的 - 版本,不工作GCC和太阳C编译器在相同parseMonth()的:
的#include<&stdio.h中GT;/ * MONTH_ code(月/)也不会降低到一个整型常量* /
的#define MONTH_ code(X)((((((X [0]&下;&下; 8)| X [1])&所述;&下; 8)| X [2])&所述;&下; 8) | X [3])的#define MONTH_JAN((((((J&所述;&下; 8)|'一')所述;&下; 8)|'n'个)下;&下; 8)|'/')
#定义MONTH_FEB(((((('F'<< 8)|E)LT;< 8)|'B')LT;< 8)|'/')
的#define MONTH_MAR((((((M&所述;&下; 8)|'一')所述;&下; 8)|为'r')所述;&下; 8)|'/')
#定义MONTH_APR(((((('A'<< 8)|'P')LT;< 8)|'R')<< 8)|'/')
的#define MONTH_MAY((((((M&所述;&下; 8)|'一')所述;&下; 8)|'y')的&所述;&下; 8)|'/')
#定义MONTH_JUN(((((('J'<< 8)|'U')LT;< 8)|'N')LT;< 8)|'/')
#定义MONTH_JUL(((((('J'<< 8)|'U')LT;< 8)|'L')LT;< 8)|'/')
#定义MONTH_AUG(((((('A'<< 8)|'U')LT;< 8)|'G')LT;< 8)|'/')
#定义MONTH_SEP(((((('S'<< 8)|E)LT;< 8)|'P')LT;< 8)|'/')
#定义MONTH_OCT(((((('O'<< 8)|'C')<< 8)|'T')LT;< 8)|'/')
#定义MONTH_NOV(((((('N'<< 8)|'O')LT;< 8)|'V')LT;< 8)|'/')
#定义MONTH_DEC(((((('D'<< 8)|E)LT;< 8)|'C')<< 8)|'/')静态INT parseMonth(为const char *输入){
INT RV = -1;
INT inputInt = 0;
INT I = 0; 对于(I = 0; I&4;放大器;&放大器;输入由[i];我++){
inputInt =(inputInt&所述;&下; 8)|输入[I]
} 开关(inputInt){
案例MONTH_JAN:RV = 0;打破;
案例MONTH_FEB:RV = 1;打破;
案例MONTH_MAR:RV = 2;打破;
案例MONTH_APR:RV = 3;打破;
案例MONTH_MAY:RV = 4;打破;
案例MONTH_JUN:RV = 5;打破;
案例MONTH_JUL:RV = 6;打破;
案例MONTH_AUG:RV = 7;打破;
案例MONTH_SEP:RV = 8;打破;
案例MONTH_OCT:RV = 9;打破;
案例MONTH_NOV:RV = 10;打破;
案例MONTH_DEC:RV = 11;打破;
} 返回rv;
}静态常量结构
{
字符*的数据;
INT结果;
} test_case [] =
{
{一月/,0},
{二月/,1},
{月/,2},
{四月/,3},
{五月/,4},
{君/,5},
{七月/,6},
{月/,7},
{月/,8},
{月/,9},
{月/,10},
{DEC /,11},
{AJ / N,-1},
{/ NAJ,-1},
};DIM的#define(X)(sizeof的(X)/ sizeof的(*(X)))INT主要(无效)
{
为size_t我;
INT结果; 对于(i = 0; I< DIM(test_case);我++)
{
结果= parseMonth(test_case [I]。数据);
如果(结果!= test_case [I]。结果)
的printf(!! FAIL !!%S(得到%d,就想%D)\\ n
test_case [I]。数据,结果,test_case [I]。结果);
}
返回(0);
}
我想用MONTH_ code(),但编译器不配合。
I was hanging out in my profiler for a while trying to figure out how to speed up a common log parser which was bottlenecked around the date parsing, and I tried various algorithms to speed things up.
The thing I tried that was fastest for me was also by far the most readable, but potentially non-standard C.
This worked quite well in GCC, icc, and my really old and picky SGI compiler. As it's a quite readable optimization, where doesn't it do what I want?
static int parseMonth(const char *input) {
int rv=-1;
int inputInt=0;
int i=0;
for(i=0; i<4 && input[i]; i++) {
inputInt = (inputInt << 8) | input[i];
}
switch(inputInt) {
case 'Jan/': rv=0; break;
case 'Feb/': rv=1; break;
case 'Mar/': rv=2; break;
case 'Apr/': rv=3; break;
case 'May/': rv=4; break;
case 'Jun/': rv=5; break;
case 'Jul/': rv=6; break;
case 'Aug/': rv=7; break;
case 'Sep/': rv=8; break;
case 'Oct/': rv=9; break;
case 'Nov/': rv=10; break;
case 'Dec/': rv=11; break;
}
return rv;
}
Solaris 10 - SPARC - SUN Compiler.
Test code:
#include <stdio.h>
static int parseMonth(const char *input) {
int rv=-1;
int inputInt=0;
int i=0;
for(i=0; i<4 && input[i]; i++) {
inputInt = (inputInt << 8) | input[i];
}
switch(inputInt) {
case 'Jan/': rv=0; break;
case 'Feb/': rv=1; break;
case 'Mar/': rv=2; break;
case 'Apr/': rv=3; break;
case 'May/': rv=4; break;
case 'Jun/': rv=5; break;
case 'Jul/': rv=6; break;
case 'Aug/': rv=7; break;
case 'Sep/': rv=8; break;
case 'Oct/': rv=9; break;
case 'Nov/': rv=10; break;
case 'Dec/': rv=11; break;
}
return rv;
}
static const struct
{
char *data;
int result;
} test_case[] =
{
{ "Jan/", 0 },
{ "Feb/", 1 },
{ "Mar/", 2 },
{ "Apr/", 3 },
{ "May/", 4 },
{ "Jun/", 5 },
{ "Jul/", 6 },
{ "Aug/", 7 },
{ "Sep/", 8 },
{ "Oct/", 9 },
{ "Nov/", 10 },
{ "Dec/", 11 },
{ "aJ/n", -1 },
};
#define DIM(x) (sizeof(x)/sizeof(*(x)))
int main(void)
{
size_t i;
int result;
for (i = 0; i < DIM(test_case); i++)
{
result = parseMonth(test_case[i].data);
if (result != test_case[i].result)
printf("!! FAIL !! %s (got %d, wanted %d)\n",
test_case[i].data, result, test_case[i].result);
}
return(0);
}
Results (GCC 3.4.2 and Sun):
$ gcc -O xx.c -o xx
xx.c:14:14: warning: multi-character character constant
xx.c:15:14: warning: multi-character character constant
xx.c:16:14: warning: multi-character character constant
xx.c:17:14: warning: multi-character character constant
xx.c:18:14: warning: multi-character character constant
xx.c:19:14: warning: multi-character character constant
xx.c:20:14: warning: multi-character character constant
xx.c:21:14: warning: multi-character character constant
xx.c:22:14: warning: multi-character character constant
xx.c:23:14: warning: multi-character character constant
xx.c:24:14: warning: multi-character character constant
xx.c:25:14: warning: multi-character character constant
$ ./xx
$ cc -o xx xx.c
$ ./xx
!! FAIL !! Jan/ (got -1, wanted 0)
!! FAIL !! Feb/ (got -1, wanted 1)
!! FAIL !! Mar/ (got -1, wanted 2)
!! FAIL !! Apr/ (got -1, wanted 3)
!! FAIL !! May/ (got -1, wanted 4)
!! FAIL !! Jun/ (got -1, wanted 5)
!! FAIL !! Jul/ (got -1, wanted 6)
!! FAIL !! Aug/ (got -1, wanted 7)
!! FAIL !! Sep/ (got -1, wanted 8)
!! FAIL !! Oct/ (got -1, wanted 9)
!! FAIL !! Nov/ (got -1, wanted 10)
!! FAIL !! Dec/ (got -1, wanted 11)
$
Note that the last test case still passed - that is, it generated a -1.
Here's a revised - more verbose - version of parseMonth() which does work the same under both GCC and Sun C compiler:
#include <stdio.h>
/* MONTH_CODE("Jan/") does not reduce to an integer constant */
#define MONTH_CODE(x) ((((((x[0]<<8)|x[1])<<8)|x[2])<<8)|x[3])
#define MONTH_JAN (((((('J'<<8)|'a')<<8)|'n')<<8)|'/')
#define MONTH_FEB (((((('F'<<8)|'e')<<8)|'b')<<8)|'/')
#define MONTH_MAR (((((('M'<<8)|'a')<<8)|'r')<<8)|'/')
#define MONTH_APR (((((('A'<<8)|'p')<<8)|'r')<<8)|'/')
#define MONTH_MAY (((((('M'<<8)|'a')<<8)|'y')<<8)|'/')
#define MONTH_JUN (((((('J'<<8)|'u')<<8)|'n')<<8)|'/')
#define MONTH_JUL (((((('J'<<8)|'u')<<8)|'l')<<8)|'/')
#define MONTH_AUG (((((('A'<<8)|'u')<<8)|'g')<<8)|'/')
#define MONTH_SEP (((((('S'<<8)|'e')<<8)|'p')<<8)|'/')
#define MONTH_OCT (((((('O'<<8)|'c')<<8)|'t')<<8)|'/')
#define MONTH_NOV (((((('N'<<8)|'o')<<8)|'v')<<8)|'/')
#define MONTH_DEC (((((('D'<<8)|'e')<<8)|'c')<<8)|'/')
static int parseMonth(const char *input) {
int rv=-1;
int inputInt=0;
int i=0;
for(i=0; i<4 && input[i]; i++) {
inputInt = (inputInt << 8) | input[i];
}
switch(inputInt) {
case MONTH_JAN: rv=0; break;
case MONTH_FEB: rv=1; break;
case MONTH_MAR: rv=2; break;
case MONTH_APR: rv=3; break;
case MONTH_MAY: rv=4; break;
case MONTH_JUN: rv=5; break;
case MONTH_JUL: rv=6; break;
case MONTH_AUG: rv=7; break;
case MONTH_SEP: rv=8; break;
case MONTH_OCT: rv=9; break;
case MONTH_NOV: rv=10; break;
case MONTH_DEC: rv=11; break;
}
return rv;
}
static const struct
{
char *data;
int result;
} test_case[] =
{
{ "Jan/", 0 },
{ "Feb/", 1 },
{ "Mar/", 2 },
{ "Apr/", 3 },
{ "May/", 4 },
{ "Jun/", 5 },
{ "Jul/", 6 },
{ "Aug/", 7 },
{ "Sep/", 8 },
{ "Oct/", 9 },
{ "Nov/", 10 },
{ "Dec/", 11 },
{ "aJ/n", -1 },
{ "/naJ", -1 },
};
#define DIM(x) (sizeof(x)/sizeof(*(x)))
int main(void)
{
size_t i;
int result;
for (i = 0; i < DIM(test_case); i++)
{
result = parseMonth(test_case[i].data);
if (result != test_case[i].result)
printf("!! FAIL !! %s (got %d, wanted %d)\n",
test_case[i].data, result, test_case[i].result);
}
return(0);
}
I wanted to use MONTH_CODE() but the compilers did not cooperate.
这篇关于是否有未能编译这个C编译器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!