gcc中的奇怪编译仅在警告时才正确

时间:2014-04-29 14:51:07

标签: c pointers gcc warnings

我有一个非常奇怪的编译问题。

我想制作十六进制/十进制转换库(没有stdio)。

这是没有警告但结果为假(应该是2014)的输出:

xx@xxx:~/fcgi/test# sudo gcc dec.c -lm -o dec
xx@xxx:~/fcgi/test# ./dec 7DE
0

当有警告但结果正确时输出!

xx@xxx:~/fcgi/test# sudo gcc dec.c -lm -o dec
In file included from libhex.h:24:0,
                 from dec.c:2:
libhex.c: In function ‘ishexchar’:
libhex.c:54:12: warning: comparison between pointer and integer [enabled by default]
libhex.c:54:23: warning: comparison between pointer and integer [enabled by default]
libhex.c:54:33: warning: comparison between pointer and integer [enabled by default]
libhex.c:54:45: warning: comparison between pointer and integer [enabled by default]
libhex.c:54:55: warning: comparison between pointer and integer [enabled by default]
libhex.c:54:66: warning: comparison between pointer and integer [enabled by default]
xx@xxx:~/fcgi/test# ./dec 7DE
2014

这是函数的代码,它正在检查十六进制字符的正确代码,错误很小(c之前没有*)但工作函数是:

int ishexchar (const int *c) {
    return (c < 48 || (c > 57 && c < 65) || (c > 70 && c < 97) || c > 102) ? 1 : 0;
};

它被称为这样(其中c是用int铸造的字符)

ishexchar(&c);

感谢您的阅读。如果你有相同的编译问题告诉我。并且还告诉我,如果这种类型的图书馆会让你感兴趣,因为我会在问题解决后立即在github上发布代码。为了我的目的,它在FastCGI中使用,它没有完全实现stdio。

编辑:这里是我为十六进制/十进制转换所做的librairy的github:https://github.com/kevmuret/libhex

2 个答案:

答案 0 :(得分:0)

嗯,你显然正在做警告所说的,即将指针与整数进行比较。

如果cconst int *,则c < 48会比较指针和整数。

将指针传递给这样的函数是没有意义的;删除*并将其设为

bool ishexchar(int c);

如果你真的想要传递指针,你需要在函数内取消引用该指针,即使用*c来获得c指向的值。我没有看到关于&#34;重复记忆的观点&#34;但是,你真的不需要传递指针,因为角色不大于没有胜利的指针。

此外,你永远不应该有#34;魔法常数&#34;在你的代码中你可以避免它。除非您尝试仅定位ASCII,否则对于小数位数,比较应该针对'0''9'。您不能依赖字符A-F和a-f来进行任何特定的排序或编码,因此如果您不想仅使用ASCII,则必须以不同的方式进行这些测试。

最后,所有布尔值的数值结果将为0或1,使用?:强迫它没有意义。

答案 1 :(得分:0)

缺少的*错误。您的函数就是将指针值(内存地址)与整数进行比较。这解释了警告,它告诉你字面你正在做什么,以及为什么这可能是错误的。

在与int比较时更改函数的签名或取消引用指针(比较实际的int值):

return (*c < 48 || (*c > 57 && *c < 65) || (*c > 70 && *c < 97) || *c > 102) ? 1 : 0;

或写:

int ishexchar (int c)
{}
//and call like:
ishexchar(c);

PS:

您不需要将char转换为int,您可以将charint进行比较:

char x = 'a';
if (x == 97)
   puts("This is perfectly valid");

不确定您的功能:c < 48表示您认为"!之类的字符是有效的十六进制字符。我不会。有效字符IMO为0-9,a-f和A-F。不多也不少:

int ishexchar(int c)
{
    return ((c > 47 && c < 58) || (c > 96 && c < 103) || (c > 64 && c < 71) ? 1 : 0);
}

这应该可以解决问题,参见codepad

请记住这一点:The ASCII table