Home > Back-end >  Is there no gcc warning when a literal declared as long is assigned to an int in c?
Is there no gcc warning when a literal declared as long is assigned to an int in c?

Time:12-02

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?

$ 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)

CodePudding user response:

Compilers should check the value range, not the type of the integer constant. Otherwise we would end up with a lot of whining whenever we initialize a small integer type, since there are no small integer constants smaller than int.

short i = 32768; does for example yield a warning with clang -Wconstant-conversion but not with gcc. There's -Wconversion but it's prone to false positives on either compiler.

If you want to guard against implicit conversions between various integer types, you should probably use a static analyser instead.

CodePudding user response:

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:

long y = 1;
int x = y;

If you add the -Wconversion flag (not included in either -Wall or -Wextra), you'll get this warning:

x1.c:6:5: warning: conversion to ‘int’ from ‘long int’ may alter its value [-Wconversion]
     int x = y;

CodePudding user response:

The compiler will automatically convert between most primitive integer types. When you convert from a larger type to a smaller type, I'm pretty sure its a feature of the C language that the number will be truncated.

For example, the following code will print "0xef":

#include <stdio.h>
#include <stdint.h>
int main() {
  uint32_t x = 0xdeadbeef;
  uint8_t y = x;
  printf("0x%x\n", y);
  return 0;
}

To address your question specifically, I don't think there is a warning for this behavior, because this conversion is technically a defined feature of the C language.

  • Related