赋值表达式隐含的转换

Conversions implied by assignment expressions

标准6.5.16章节有2段:

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.

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

所以考虑下面的代码:

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

if都是算术类型所以f应该转换成i。虽然编译代码会产生错误:

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

但是当添加显式强制转换时它编译得很好:

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

那么在赋值表达式中允许什么样的转换呢?我虽然标准中的转换等同于强制转换 (type).

更新:

GCC 9.3.0

这是我的旗帜:

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

来自 gcc - wiki(自 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" } */