Compiler Error c2398 narrowing conversion - c++

So I have seen this quest a few times and I have tried wrapping it with static_cast(WIDTH) and static_cast(HEIGHT) however it just produces the same error and I am not too sure why it seem to me int to float shouldnt even need a narrowing conversion. I am currently learning ImGui and am getting this error when i compile
Error C2398 Element '1': conversion from 'const int' to 'float' requires a narrowing conversion
This is my code
constexpr int WIDTH = 500;
constexpr int HEIGHT = 300;
}
//it is referenced later in this line in a different file that DOES include the header
void gui::Render() noexcept
{
ImGui::SetNextWindowSize({ WIDTH, HEIGHT });
}
//I have attempted to do a simple float conversion but it still screams at me with the same error

Related

Warnings on sign conversion when assigning from the result of unsigned division

I compiled the following code with -Wsign-conversion :
int main()
{
unsigned int a = 8;
int b = a + 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int c = a - 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int d = a * 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int e = a / 8u; // gcc warns, but no warning in clang
}
Clang doesn't emit a warning when assigning from the result of an unsigned division, but gcc does.
Why is there a difference in this one particular case?
Clang is just being an extra bit clever: division of an unsigned integer by an unsigned integer larger or equal to 2 means the unsigned integer result will always fit in the signed integer counterpart (to that of the numerator type in the division expression). However, if you divide by an unsigned integer valued 1, the result is no longer guaranteed to fit in a signed integer counterpart, and Clang does emit a warning:
#include <cstdint>
int main() {
uint8_t a = 240; // '240 / 1' will not fit in int8_t
int8_t e = a / 2u; // No warning in clang
int8_t f = a / 1u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int8_t' (aka 'signed char') [-Wsign-conversion]
}
One could also argue that Clang should be able to omit the warning for the similar special case of multiplication by 0; however Clang does not whereas GCC, instead, does:
// Clang warns, no warning in GCC.
int8_t g = a * 0u;
So peculiarly Clang is clever, in this context, w.r.t. division and GCC w.r.t. multiplication.
Finally, note that the gating for Clang to emit this warning during division seems to be only when dividing by 1, as you will not get the same -Wsign-conversion if you divide by 0u; arguably as it has been overridden by the more relevant (in such a context) -Wdivision-by-zero warning:
int8_t h = a / 0u;
warning: division by zero is undefined [-Wdivision-by-zero]

error: narrowing conversion of ‘199’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]

I am trying to compile a really old software in linux debian 9.5, i keep getting this error:
janpdf/PDF.cpp: In member function ‘void PDF::OpenFile(const char*)’:
janpdf/PDF.cpp:41:74: error: narrowing conversion of ‘199’ from ‘int’ to
‘char’ inside { } [-Wnarrowing]
char signature[] = {'%', '%', 'G' + 128, 'R' + 128, 'A' + 128, '\n', 0};
^
janpdf/PDF.cpp:41:74: error: narrowing conversion of ‘210’ from ‘int’ to
‘char’ inside { } [-Wnarrowing]
janpdf/PDF.cpp:41:74: error: narrowing conversion of ‘193’ from ‘int’ to
‘char’ inside { } [-Wnarrowing]
Makefile:153: recipe for target 'janpdf/PDF.o' failed
make: *** [janpdf/PDF.o] Error 1
I have already tried teh signed / unsigned 'char'approach. Although I know almos nothing about coding this is the only answer I found. Any other solution is welcome.
thanks
Well, apparently in your implementation values like 210 and 199 do not fit into the range of type char. So, the conversion is narrowing. {} initializers do not allow narrowing conversions.
This suggests that your implementation apparently uses signed char type.
You can forcefully convert the values to char by using explicit casts inside the {}. You can stop using {} initializers. You can force your implementation to use unsigned char. There are many "solutions" for this problem, but there's no way to chose one without more context.
If the code was originally written for the same "family" of implementations you are compiling it on now, then most likely it was simply written for an older version of the language, which performed that narrowing conversion implicitly. In that case to reproduce the old behavior you'll need explicit casts
char signature[] =
{'%', '%', (char) ('G' + 128), (char) ('R' + 128), (char) ('A' + 128), '\n', 0};
The lowest-effort way to get your thing to build is probably to add -Wno-narrowing to your compiler invocation. If you're using make, you can probably start it with something like CFLAGS=-Wno-narrowing make (assuming you're using bash) to get the desired effect.
Current compilers use by default newer versions of C++. Your compiler may be trying to compile the source in C++11 or C++14 mode.
Try adding -std=c++03 to your compiler flags.

C++ / OpenGL: Texture to pixmap example - narrowing conversion error

I am trying to run this texture to pixmap example from OpenGL and get the following error
tex_to_pix.cpp:40:1: error: narrowing conversion of ‘4294967295u’ from ‘unsigned int’ to ‘int’ inside { } [-Wnarrowing]
The error refers to the following code block of the example:
const int pixmap_config[] = {
GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
GLX_DOUBLEBUFFER, False,
GLX_Y_INVERTED_EXT, GLX_DONT_CARE,
None
};
What is the reason for this error?
Is it a compiler or c++11 problem?
Is there a way i can either make my compiler ignore -Wnarrowing or make a safe conversion?
The issue is with GLX_DONT_CARE which is defined as:
#define GLX_DONT_CARE 0xFFFFFFFF
Because this value does not fit into a 32-bit int, its type is unsigned int (see this answer). The rules for narrowing conversion were indeed changed in c++11.
Trying to implicitly convert this unsigned int into an int causes the narrowing conversion warning. As shown in this answer, the narrowing problem can be fixed by using static_cast(GLX_DONT_CARE & 0xFFFFFFFF) instead of GLX_DONT_CARE
const int pixmap_config[] = {
GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
GLX_DOUBLEBUFFER, False,
GLX_Y_INVERTED_EXT, static_cast<int>(GLX_DONT_CARE & 0xFFFFFFFF),
None
};
Alternatively, disable narrowing conversion errors in your compiler (unspecified).

c++ float vector does not recognize float number? [duplicate]

Check out this simple program:
int main() {
float f2 = 7.2; // OK, with warning
float f3 = 7.199999809265137; // OK, no warning
float f4{ 7.2 }; // Fails
float f5{ 7.199999809265137 }; // OK, no warning
float f6 = { 7.2 }; // Fails
float f7 = { 7.199999809265137 }; // OK, no warning
}
When compiled with MSVC 2015 using the default options (cl /W4, version 19.00.23918), I get the following messages:
FloatTest.cpp(2): warning C4305: 'initializing': truncation from 'double' to 'float'
FloatTest.cpp(4): error C2397: conversion from 'double' to 'float' requires a narrowing conversion
FloatTest.cpp(4): warning C4305: 'initializing': truncation from 'double' to 'float'
FloatTest.cpp(6): error C2397: conversion from 'double' to 'float' requires a narrowing conversion
FloatTest.cpp(6): warning C4305: 'initializing': truncation from 'double' to 'float'
This program compiles fine with Clang 3.0-3.8 and GCC 4.5.4-6.1.0 (tested with http://melpon.org/wandbox), with only warnings for unused variables. Further, removing/commenting out lines f4 and f6 result in successful compilation (with only the one warning for line f2).
Initially it looks like MSVC is just telling me that 7.2 can't be represented precisely as a float, so it's a narrowing conversion (which is illegal in brace initialization). However, the standard (draft N3337), section 8.5.4, note 7, says this:
A narrowing conversion is an implicit conversion...
from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly)
Emphasis mine. Since 7.2 is within the range of values representable by float, its conversion to float should not be a narrowing conversion according to the standard. Is MSVC in the wrong here, and should I file a bug?
It looks like a bug, indeed. For a workaround, the following appears to silence both errors and warnings in MSVC 2015.
#pragma float_control(precise, off, push)
float f2 = 7.2; // OK, with warning
//...
#pragma float_control(precise, pop)
The same works globally if using the /fp:fast compiler switch, though that one is incompatible with /Za which disables MS language extensions.
Some floating point numbers can be exactly expressed in a float representation and some can't. If the number can be represented in the form x / 2^y where x is any integer and y is an integer 23 or less, it fits. Most decimal numbers can't be represented in this way, as a binary number they repeat forever. 7.2 is one example.
You can fix this easily by appending f to each number, to indicate to the compiler that this is a float constant rather than a double.
float f4{ 7.2f };

Can't convert from 'int' to 'int *'

So I have these lines of code:
int maxY, maxX;
getmaxyx(stdscr, &maxY, &maxX);
It gives me the following error:
error C2440: '=' : cannot convert from 'int' to 'int *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
twice for each time I use it. I'm not even using the = operator! The curses.h file is included. What am I doing wrong?
getmaxyx is a macro, which doesn't take int*, but int.
It resolves to something like
getmaxyx(S,Y,X) -> X=s->X, Y=s->Y
try
getmaxyx(stdscr, maxY, maxX); // without the & operator
see http://opengroup.org/onlinepubs/007908775/xcurses/getmaxyx.html