I can compile and run a program that assigns a long int literal, albeit it one that would fit into an int, to an int variable.
$ cat assign-long-to-int.c
#include <stdio.h>
int main(void){
int i = 1234L; //assign long to an int
printf("i: %d\n", i);
return 0;
}
$ gcc assign-long-to-int.c -o assign-long-to-int
$ ./assign-long-to-int
i: 1234
I know that 1234 would fit into an int but would still expect to be able to enable a warning. I've been through all the gcc options but can't find anything suitable.
Is it possible to generate a warning for this situation? From the discussion here, and the gcc options, the short answer is no. It isn't possible.
Would there be any point in such a warning? It's obvious in the trivial example I posted that 1234L is being assigned to an int variable, and that it will fit. However, what if the declaration and the assignment were separated by many lines of code? The programmer writing 1234L is signaling that they expect this literal integer to be assigned to a long. Otherwise, what's the point of appending the L?
In some situations, appending the L does make a difference. For example
$ cat sizeof-test.c
#include <stdio.h>
void main(void){
printf("%ld\n", sizeof(1234));
printf("%ld\n", sizeof(1234L));
}
$ ./sizeof-test
4
8
Although the compiler must know that 1234L would fit into a 4 byte int, it puts it into an 8 byte long.
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
In the case of constants, the compiler can see that the value in question fits into the type being assigned to, so there's really no point in warning. If the constant was out of range, i.e.
5000000000L
, then the compiler will see that and generate a warning.What the compiler can do however is warn when an integer type that is not a compile type constant is assigned to a lower type:
If you add the
-Wconversion
flag (not included in either-Wall
or-Wextra
), you'll get this warning: