【问题标题】:gcc long long int width same as int [duplicate]gcc long long int width 与 int 相同 [重复]
【发布时间】:2020-04-11 11:16:51
【问题描述】:

我正在测试 gcc 版本 8.2

gcc 似乎将long long int 视为int。有没有什么办法解决这一问题?

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>

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

    printf("INT_MAX     :   %d\n", INT_MAX);
    printf("INT_MIN     :   %d\n", INT_MIN);
    printf("LONG_MAX    :   %ld\n", (long) LONG_MAX);
    printf("LONG_MIN    :   %ld\n", (long) LONG_MIN);
    printf("UINT_MAX    :   %u\n", (unsigned int) UINT_MAX);
    printf("ULLONG_MAX   :   %lu\n", (unsigned long long int) ULLONG_MAX);
    printf("Big Integer   :   %lu\n", (unsigned long long int) 1234567890123456);

    printf("%d\n", sizeof(long long int));
    return 0;
}

输出:

INT_MAX     :   2147483647
INT_MIN     :   -2147483648
LONG_MAX    :   2147483647
LONG_MIN    :   -2147483648
UINT_MAX    :   4294967295
ULLONG_MAX   :   4294967295
Big Integer   :   1015724736
8

C:\prog_c\c_pro>gcc --version gcc (MinGW.org GCC-8.2.0-5) 8.2.0 版权所有 (C) 2018 Free Software Foundation, Inc...

【问题讨论】:

  • unsigned long long 需要%llu 格式,我相信
  • @SteveFriedl 现在可以使用
  • 另外,size_tsizeof 表达式的类型)的正确格式是 %zu
  • 始终使用-Wall 编译并阅读警告

标签: c gcc 64-bit long-integer


【解决方案1】:

printf 需要知道longlong long 之间的区别,那就是%lld(有符号)或%llu(无符号):

    printf("ULLONG_MAX  :   %llu\n", (unsigned long long int) ULLONG_MAX);
    printf("Big Integer :   %llu\n", (unsigned long long int) 1234567890123456);

这应该可以如您所愿。否则, printf 只会从堆栈中获取部分位,从而给出错误的答案。

此外,如果您打开编译器警告,它会告诉您:

long.c: In function ‘main’:
long.c:13:5: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘long long unsigned int’ [-Wformat=]
     printf("ULLONG_MAX  :   %lu\n", (unsigned long long int) ULLONG_MAX);
     ^
long.c:14:5: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘long long unsigned int’ [-Wformat=]
     printf("Big Integer :   %lu\n", (unsigned long long int) 1234567890123456);
     ^
long.c:16:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]

始终打开警告是一个非常非常好的主意 - 对于 GCC,我通常使用 -W -Wall - 所以它告诉我我哪里出错了。

编译器警告类似于 SO,但没有反对意见 :-)

【讨论】:

  • 使用 -W -Wall 并且现在在修复 printf("ULLONG_MAX : %llu\n", (unsigned long long) ULLONG_MAX) 后说“格式中的未知转换类型字符 'l'” ;
  • 嗯,这很奇怪,因为%llu 应该是正确的。你确定它指向那条线吗?
  • c_pro2.c:15:32: 警告:未知转换类型字符 'l' 格式 [-Wformat=] printf("ULLONG_MAX : %llu\n", (unsigned long long) ULLONG_MAX) ;
  • 也许这是相关的? stackoverflow.com/questions/23718110/…
【解决方案2】:

您使用了错误的格式说明符进行打印。

unsigned long long int 需要使用 %llu 格式说明符。您使用的是%lu,它是unsigned long int。格式说明符与类型不匹配会调用undefined behavior

在这种情况下可能发生的情况是unsigned long long 值的前 4 个字节被读取为unsigned long

这样打印:

printf("ULLONG_MAX   :   %llu\n", (unsigned long long int) ULLONG_MAX);
printf("Big Integer   :   %llu\n", (unsigned long long int) 1234567890123456);

您应该会看到预期的结果。

【讨论】:

    猜你喜欢
    • 2011-05-08
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多