gnychis
gnychis

Reputation: 7555

warning: "integer constant too large for long type" ... but it is a uint64_t?

I am working on cross-compiling libbtbb to Android, and I am getting a ton of warnings that say:

jni/libbtbb/bluetooth_packet.h:67: warning: integer constant is too large for 'long' type

However, when I dig in to the file, this points to the line:

static const uint64_t sw_matrix[] = {
    0xfe000002a0d1c014, 0x01000003f0b9201f, 0x008000033ae40edb, 0x004000035fca99b9,
    0x002000036d5dd208, 0x00100001b6aee904, 0x00080000db577482, 0x000400006dabba41,
    0x00020002f46d43f4, 0x000100017a36a1fa, 0x00008000bd1b50fd, 0x000040029c3536aa,
    0x000020014e1a9b55, 0x0000100265b5d37e, 0x0000080132dae9bf, 0x000004025bd5ea0b,
    0x00000203ef526bd1, 0x000001033511ab3c, 0x000000819a88d59e, 0x00000040cd446acf,
    0x00000022a41aabb3, 0x0000001390b5cb0d, 0x0000000b0ae27b52, 0x0000000585713da9};

The type is uint64_t, and not "long" ... but it seems to be referring to specifying the constant like 0xfe000002a0d1c014. In this case, I'm not sure how else it should be specified, or if I can ignore these warnings.

Upvotes: 3

Views: 4404

Answers (2)

Keith Thompson
Keith Thompson

Reputation: 263347

In the 1989/1990 version of the C standard, the type of a hexadecimal integer constant is the first in this list in which its value can be represented:

  • int
  • unsigned int
  • long int
  • unsigned long int

That version of the language had no long long or unsigned long long type.

The 1999 version of the standard, this list was changed to:

  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int
  • unsigned long long int

It looks like you're using gcc, which by default recognizes C89/C90 with some GNU-specific extensions. My understanding is that it provides types long long and unsigned long long as an extension, but doesn't change the semantics of integer constants.

If you invoke gcc with the argument -std=c99, it will (attempt to) conform to the C99 standard, and the warnings should go away (no need to change your source code).

If you want to modify your source so it compiles without warnings without -std=c99, then adding a ULL suffix will cause the constants to be of type unsigned long long, which is probably the same type as uint64_t, but it's not guaranteed. Using the UINT64_C() macro ensures they're of the correct type, but it's a bit verbose.

Upvotes: 3

ouah
ouah

Reputation: 145859

Add the ULL suffix to your 64-bit integer constants or enclose them in the verbose UINT64_C macro from stdint.h.

static const uint64_t sw_matrix[] = {
    0xfe000002a0d1c014ULL, /* etc. */ };

or

#include <stdint.h>

static const uint64_t sw_matrix[] = {
    UINT64_C(0xfe000002a0d1c014), /* etc. */ };

Upvotes: 7

Related Questions