You are not logged in.
Hi, compiling an old programm with gcc6 fails with some -Wnarrowing errors. Using -std=gnu++98 (edit: or -Wno-narrowing) solve the problem but now I'm wondering how to fix the sources properly.
Here is a small example (narrow.cpp)
#include <iostream>
int main(void)
{
unsigned int a[3] = {1 ,2 ,-1};
std::cout << a[2] << std::endl;
return 0;
}
compiling with gcc6 defauld standard fails
g++ -o narrow narrow.cpp
narrow.cpp: In function 'int main()':
narrow.cpp:5:32: error: narrowing conversion of '-1' from 'int' to 'unsigned int' inside { } [-Wnarrowing]
unsigned int a[3] = {1 ,2 ,-1};
^
The Porting to gcc-6 guide says: Narrowing conversions can be avoided by using an explicit cast
So I tried this (narrow-cast.cpp)
#include <iostream>
int main(void)
{
unsigned int a[3] = {1 ,2 ,(unsigned int)-1};
std::cout << a[2] << std::endl;
return 0;
}
Results:
g++ -std=gnu++98 -o narrow narrow.cpp
g++ -o narrow-cast narrow-cast.cpp
./narrow
4294967295
./narrow-cast
4294967295
Looks good, but I'm not sure if the cast is a proper fix or if there are any possible pitfalls?
Last edited by mis (2016-11-19 16:28:44)
Offline
In my mind, casting a signed value to an unsigned variable is an error. Regardless, the conversion is to take the absolute value of the signed value, compliment each bit, and add one. The resultant value, of course, is dependent on the size of int on the system. A value of -1 therefore becomes 0b11111..1111. IOW, the largest unsigned value that can be expresses as an unsigned int.
You will need to audit the code to determine where a[] is used, and determine what is the acceptable domain. Is the domain all unsigned ints? or is it limited to the domain of a[] over the range 0..2?
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
In my mind, casting a signed value to an unsigned variable is an error.
Hm, that was my thought also.
You will need to audit the code to determine where a[] is used, and determine what is the acceptable domain. Is the domain all unsigned ints? or is it limited to the domain of a[] over the range 0..2?
It's a mp3 player siftware and the code in question is a huffman table.
typedef struct
{
int tablename;
unsigned int xlen,ylen;
unsigned int linbits;
unsigned int treelen;
const unsigned int (*val)[2];
}HUFFMANCODETABLE;
The narrowing coversion is where such a struct is declared and initialized. Some values are -1
But ok, to determine if the cast wouldn't break anything is above my skills and seems too much work.
I'll stick with -std=gnu++98 for the moment...
edit:
Hm.. but then comes the question to mind how it's handled by the gnu++98 standard?
Last edited by mis (2016-11-19 17:25:56)
Offline
I guess most correct way is to use std::numeric_limits<unsigned int>::max() value instead of -1.
Offline