4

I'm using MS Visual Studio 2017 and (as expected) I get the compiler warning:

Warning C4244   '=': conversion from 'unsigned long' to 'unsigned short', possible loss of data

on this C++ code:

unsigned long test32{70000};
unsigned short test16;
test16 = test32;

However, when I use the cstdint typedefs:

uint32_t test32{70000};
uint16_t test16;
test16 = test32;

...I don't get any compiler warnings at all. Why?

Furthermore, as a strictly-typed language, shouldn't a C++ compiler be giving me errors instead of warnings for either of these approaches (and force me to explicitly cast the 32-bit value to 16-bits prior to assignment in the third line)?

sepp2k
  • 363,768
  • 54
  • 674
  • 675
NKatUT
  • 429
  • 3
  • 10
  • I'm inclined to agree that the latter set should also give you warnings. You'd probably want to see what 2017 typedefs uint32_t and uint16_t to, to see if there's a potential reason why they're treated differently. If they typedef to unsigned long and unsigned short, but behave differently from using those types directly, then that's likely a bug and it needs to be reported. If they typedef to something else... well, it's probably a bug of a different type, and ought to be reported as well. But knowing the details in order to report them would probably be helpful to whomever reads the report. – Aiken Drum Dec 23 '17 at 15:44
  • 1
    "_shouldn't a C++ compiler be giving me errors instead of warnings for either of these approaches_" Since C++ standard allows for narrowing conversions, why should the compilers give errors for those? Enable treating warnings as errors, and they will be treated as errors. – Algirdas Preidžius Dec 23 '17 at 15:45
  • As an aside, I would not say C++ is strictly-typed. It would like to be, but it isn't, mostly because backcompat. Thus warnings rather than errors. – Aiken Drum Dec 23 '17 at 15:46
  • @AlgirdasPreidžius - Agreed. It's generally best to treat warnings as errors and disable the ones you can't or won't deal with on a case-by-case basis. Warnings have proven, over and over, to be pointless. Far too many programmers will not fix warnings unless forced, which means they often miss very valid warnings in miles upon miles of warning spew during compilation. Compile clean or go home. – Aiken Drum Dec 23 '17 at 15:48
  • 1
    Yes, when I hover cursor over the uint32_t or uint16_t, they show the typedefs to unsigned long and unsigned short. Thanks for confirming that this is odd behavior and not just my misunderstanding of how things should work. – NKatUT Dec 23 '17 at 16:00

1 Answers1

0

No. The standard doesn't mandate how a compiler emits a diagnostic. See [defns.diagnostic]:

message belonging to an implementation-defined subset of the implementation's output messages

Whether it is a warning or an error is up to the compiler. To answer your second question, that seems to be a QoI issue. GCC for example emits a diagnostic:

g++ -std=c++11 -Wconversion test.cpp
test.cpp: In function ‘int main()’:
test.cpp:6:10: warning: conversion to ‘uint16_t {aka short unsigned int}’ from ‘uint32_t {aka unsigned int}’ may alter its value [-Wconversion]
 test16 = test32;

You can either try messing around with the warning settings in Visual Studio or file a bug report.