Search code examples
clanguage-lawyerassignment-operator

Conversions implied by assignment expressions


There are 2 paragraphs in the 6.5.16 chapter of the Standard:

In simple assignment ( = ), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.

and

the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;

So consider the following code:

float f = 1.2f;
int i = f; //error

Both i and f have arithmetic types so f should be converted to i. The compilation of the code produces an error though:

error: conversion from ‘float’ to ‘int’ may change value [-Werror=float-conversion]
    6 |     int i = f;

But when adding explicit cast it compiles fine:

float f = 1.2f;
int i = (int) f;  //ok

So what kind of conversions are permitted in assignment expressions? I though the conversion in the Standard is equivalent to cast (type).

UPD:

GCC 9.3.0

Here are my flags:

-Werror
-Wextra
-pedantic
-Wconversion
-g3
-O3
-Wno-unused-result
-Wno-unused-parameter
-Wstrict-prototypes

Solution

  • From gcc - wiki (since v4.3)

    -Wconversion

    Warn for implicit conversions that may alter a value. This includes conversions between real and integer

      14 float  vfloat;
      15 double vdouble;
      16 
      17 void h (void)
      18 {
      19   unsigned int ui = 3;
      20   int   si = 3;
      21   unsigned char uc = 3;
      22   signed char sc = 3;
      23   float  f = 3;
      24   double d = 3;
      25 
      26   fsi (3.1f); /* { dg-warning "conversion" } */
      27   si = 3.1f; /* { dg-warning "conversion" } */
      28   fsi (3.1);  /* { dg-warning "conversion" } */
      29   si = 3.1;  /* { dg-warning "conversion" } */
      30   fsi (d);    /* { dg-warning "conversion" } */
      31   si = d;    /* { dg-warning "conversion" } */
      32   fui (-1.0); /* { dg-warning "overflow" } */
      33   ui = -1.0;   /* { dg-warning "overflow" } */
      34   ffloat (INT_MAX);  /* { dg-warning "conversion" } */
      35   vfloat = INT_MAX;  /* { dg-warning "conversion" } */
      36   ffloat (16777217); /* { dg-warning "conversion" } */
      37   vfloat = 16777217; /* { dg-warning "conversion" } */
      38   ffloat (si); /* { dg-warning "conversion" } */
      39   vfloat = si; /* { dg-warning "conversion" } */
      40   ffloat (ui); /* { dg-warning "conversion" } */
      41   vfloat = ui; /* { dg-warning "conversion" } */