Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
790 views
in Technique[技术] by (71.8m points)

c - Why does GCC give a warning when setting an unsigned long to 2^64-1?

The C standard states that a long int is at least 4 bytes - on my system it is 8 bytes.

This means I can store values up to 2^63-1 in a long and 264-1 in an unsigned long.

However, when the following code is compiled with the -Wall flag it gives the warning [Wimplicitly-unsigned-literal]:

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

  unsigned long a;
  a = 18446744073709551615; // 2^64-1

}

If I use 263-1 (9223372036854775807) instead, it compiles with no warnings (as expected - 263-1 will fit in a signed long int).

For a project I needed to have the maximum value in an unsigned long, and I discovered that (9223372036854775807 << 1) + 1 will not raise this warning. My teacher then suggested that I could use the ULONG_MAX defined in limits.h and this gave no warnings.

Why can't I do this without a warning saying it was converted implicitly - when I declared it explicitly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Per the C standard, the type of a decimal constant without a suffix is int, long int, or long long int, specifically the first of those that is sufficient to represent the value. In your C implementation, none of those can represent 18446744073709551615, because it is too large.

In order to accommodate you, the compiler is making its type unsigned long. Technically, this does not conform to the C standard, so the compiler is warning you.

In this case, no harm is caused, because you are assigning the value to an unsigned long. But there are situations in which using the wrong type can cause problems, so generally you should append a suffix to such constants to ensure they match how they are intended to be used. In this case, a u is sufficient; as with unsuffixed types, the compiler will decide whether to use unsigned int, unsigned long int, or unsigned long long int depending on the magnitude of the number and the capabilities of the types.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...