pengxihan 发表于 2009-05-22 14:10

交叉编译器打印这个warning,大家看看真正的原因是什么?

一个简单的程序:
<code>
#include <stdio.h>

int main(int argc, char **argv)
{
      char c;

      c = 0xFF;

      if ((int)c == -1) {
                printf("c == -1\n");
      } else {
               printf("Just a test!\n");
      }

      return 0;

}
</code>
用gcc编译,没有任何警告。
#gcc -o test test.c
运行的结果是打印"c == -1"

用一个交叉编译器,是freescale提供的powerpc交叉编译器powerpc-linux-gnuspe-gcc
# powerpc-linux-gnuspe-gcc -o test test.c
test.c: In function 'main':
test.c:9: warning: comparison is always false due to limited range of data type

也就是说如果这个程序在我的powerpc板子上运行结果是"Just a test!",与我的主机上运行结果是不一样的,难道是说这个交叉编译器中int类型是指正整数?

prolj 发表于 2009-05-22 14:25

#include <stdio.h>

int main(int argc, char **argv)
{
      char c;

      c = 0xFF;

      if ((int)c == -1) {
                printf("c == -1\n");
      } else {
               printf("Just a test!\n");
      }

      return 0;

}

熟练的C程序员是不会这么用的

pengxihan 发表于 2009-05-22 14:44

原帖由 prolj 于 2009-5-22 14:25 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
#include

int main(int argc, char **argv)
{
      char c;

      c = 0xFF;

      if ((int)c == -1) {
                printf("c == -1\n");
      } else {
               printf ...



呵呵,我不是熟练的C程序员,望赐教!
另外:我觉得这不是这个问题的原因吧。这是我交叉编译e2fsprogs时得到的waring,源程序中e2fsck/super.c中这个函数就是这样的:
<code>
static void e2fsck_fix_dirhash_hint(e2fsck_t ctx)
{
      struct ext2_super_block *sb = ctx->fs->super;
      struct problem_context pctx;
      char    c;

      if ((ctx->options & E2F_OPT_READONLY) ||
            !(sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
            (sb->s_flags & (EXT2_FLAGS_SIGNED_HASH|EXT2_FLAGS_UNSIGNED_HASH)))
                return;

      c = (char) 255;

      clear_problem_context(&pctx);
      if (fix_problem(ctx, PR_0_DIRHASH_HINT, &pctx)) {
                if (((int) c) == -1) {/*报警告就在这里*/
                        sb->s_flags |= EXT2_FLAGS_SIGNED_HASH;
                } else {
                        sb->s_flags |= EXT2_FLAGS_UNSIGNED_HASH;
                }
                ext2fs_mark_super_dirty(ctx->fs);
      }
}
</code>

jzhang918 发表于 2009-05-22 17:18

回复 #1 pengxihan 的帖子

这是因为 i386 上 char default 是 signed 的,最高位是符号位,0xff 就是-1,而powerpc上char default是unsigned,0xff就是0xff
所以当赋值给一个int的时候, i386上是扩展成 -1 ,powerpc上是扩展成0xff
如果你要写可移植的程序,建议用 uint8_t 或 int8_t

[ 本帖最后由 jzhang918 于 2009-5-22 17:22 编辑 ]

prolj 发表于 2009-05-22 22:19

有些人喜欢用0xff来表示自己是个熟悉底层的高手,可正是这个毛病,恰恰反应了他不能真正理解Arch。
The Art 第二卷《半数值计算》对这种问题讨论深入,如果不想看,林瑞的《高质量》也有说这个问题,不过,建议在骂林以前,先确定自己的代码功力比林高深多少。

prolj 发表于 2009-05-22 22:47

0xff有它的用途,比如判断字长,但是如果发现开源项目中有不恰当用法,patch吧,以后就可以吹牛给某某开源软件贡献过代码了。
至于ext文件系统的0xff啥意思?看看alb过来说两句不。

mik 发表于 2009-05-22 22:55

这样写确实很不好
产生 bug 的温床
为什么不用简单明了的语句表示
--------------------------------------

但是,从上面的代码看,似乎这又是个解决的好办法

                if (((int) c) == -1) {/*报警告就在这里*/
                        sb->s_flags |= EXT2_FLAGS_SIGNED_HASH;
                } else {
                        sb->s_flags |= EXT2_FLAGS_UNSIGNED_HASH;
                }

目的就是判断什么时候是 singned?什么时候是 unsigned ?
似乎没什么技巧比这要好的。。
页: [1]
查看完整版本: 交叉编译器打印这个warning,大家看看真正的原因是什么?