【问题标题】:variable definition is not correct in my code我的代码中的变量定义不正确
【发布时间】:2020-06-29 10:35:46
【问题描述】:

这是我的代码

typedef int8_t BYTE;

# define BLOCK_SIZE 512
# define file_name_size 8

bool new_jpeg(BYTE buffer[]);

int main(int argc, char *argv[])
{
    if (argc !=2)
    {
        printf("Wrong must be recover image\n");
        return 1;
    }
    FILE* infile = fopen(argv[1], "r");
    if (infile == NULL)
    {
        printf("File not found\n");
        return 1;
    }

    BYTE buffer[BLOCK_SIZE];

    int file_index = 0;

    bool foud_first_jpeg = false;
    FILE* outfile;
    while (fread(buffer,BLOCK_SIZE,1,infile))
    {
        if(new_jpeg(buffer))
        {
            if(!foud_first_jpeg)

                foud_first_jpeg = true;

            else
                fclose(outfile);

            char filename[file_name_size];
            sprintf(filename, "%03i.jpg", file_index++);
            outfile = fopen(filename, "w");
            if(outfile ==NULL)
                return 1;

            fwrite(buffer, BLOCK_SIZE,1,outfile);
        }
        else if (foud_first_jpeg)
        {
            fwrite(buffer, BLOCK_SIZE,1,outfile);
        }
    }
    fclose(outfile);
    fclose(infile);
}

bool new_jpeg(BYTE buffer[])
{
    return buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0;
}

似乎我在最后一行有错误。 错误是: 错误:常量 255 与“BYTE”类型(又名“有符号字符”)表达式的比较结果始终为假 [-Werror,-Wtautological-constant-out-of-range-compare]

我知道这是我定义 BYTE 的方式,但解决方案是什么?

谢谢

【问题讨论】:

  • BYTE 是有符号类型的原因是什么?这有点不寻常。
  • 在比较行使用转换为 uint8_t 或使用十进制负数而不是十六进制负数 (0xff ==> -128)
  • 尝试使用负 8 位等值的常量,例如-1 而不是 0xff。
  • 只要把typedef改成typedef uint8_t BYTE;

标签: c


【解决方案1】:

我知道这是我定义 BYTE 的方式,但解决方案是什么?

删除这个:typedef int8_t BYTE;永远不要对原始二进制使用有符号整数类型,你可能会遇到按位运算符的各种问题,以及溢出。

然后在任何地方用uint8_t 替换BYTE,因为一开始就不需要typedef 任何东西。不要发明自己的标准,而是使用stdint.h 给出的标准!这是迄今为止最易读的形式。

BYTE 这个名字特别有问题,因为它与 Windows API 中的一个类型发生冲突,所以在你需要使用 Windows API 时它会中断。 Win API 类型系统一般是臭名昭著的,所以可以用它来举例说明如何命名类型...


与您的问题无关,请考虑在您的函数中删除 &&,因为这会强制对编译器进行低效的逐字节评估。这样的事情会运行得更快:

bool better_new_jpeg (uint8_t buffer[])
{
    const uint32_t HEADER = 0xE0FFD8FFu;
    const uint32_t MASK   = 0xF0FFFFFFu;
    uint32_t tmp;

    memcpy(&tmp, buffer, 4);
    tmp &= MASK;
    return memcmp(&tmp, &HEADER, 4) == 0;
}

但是请注意这里的字节序,我假设你的代码中的字节序是小字节序。拆解:

better_new_jpeg:
        mov     eax, DWORD PTR [rdi]
        and     eax, -251658241
        cmp     eax, -520103681
        sete    al
        ret

【讨论】:

  • 无需太多努力就可以避免字节序依赖:const uint8_t header[4] = { 0xff, 0xd8, 0xff, 0xe0 };uint8_t tmp[4];memcpy(tmp, buffer, 4);tmp[3] &= 0xf0;return memcmp(tmp, header, 4) == 0;。 (我看不出原始代码的哪一部分假定了字节序。)
  • @IanAbbott 我一开始就是这样写的,但它给出了更多的说明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-19
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多