Consider the following code:
#include <complex>
int main()
{
unsigned u = 1u;
auto result = static_cast<std::complex<int>>(u);
return 0;
}
Compiling with
g++ -std=c++11 -Werror -Wsign-conversion -o a.out source_file.cpp
Causes compile error
source_file.cpp: In function ‘int main()’:
source_file.cpp:8:51: error: conversion to ‘int’ from ‘unsigned int’ may change the sign of the result [-Werror=sign-conversion]
auto result = static_cast<std::complex<int>>(u);
^
clang reports a similar error
source_file.cpp:6:50: error: implicit conversion changes signedness: 'unsigned int' to 'const value_type' (aka 'const int') [-Werror,-Wsign-conversion]
auto result = static_cast<std::complex<int>>(u);
~~~~~~~~~~~ ^
The error does not make much sense at first sight, what am I missing?
You get a conversion warning not from the cast, but from inside construction of std::complex.
To 'fix' your example you should instead do:
auto result = std::complex<int>{static_cast<int>(u)};
Related
I getting below warning. How to suppress this warning?
Warning:
warning: comparison of integer expressions of different signedness: 'DWORD' {aka 'unsigned int'} and 'int' [-Wsign-compare]
Code:
DWORD exp = GetExp();
int amount = 20;
if (amount < 0 && exp < -amount)
{
...
}
If you really want to suppress it (it's not recommended, there is a reason a warning is shown, and you should instead eliminate the reason), you can do it by adding -Wno-sign-compare to the gcc command line.
I'm trying to compile the following code:
#include <boost/optional.hpp>
void foo(boost::optional<unsigned> x = boost::none);
placed in the file a.cu, with the CUDA compiler, using the following command line:
nvcc a.cu -c --std=c++11 -I/opt/boost/include
but I get a bunch of errors:
a.cu:2:53: error: conversion from ‘const boost::none_t(boost::none_t::init_tag (*)())’ to ‘boost::optional<unsigned int>’ is ambiguous
void foo(boost::optional<unsigned> x = boost::none);
^
/opt/boost/include/boost/optional/optional.hpp:805:1: note: candidate: boost::optional<T>::optional(boost::optional<T>::rval_reference_type) [with T = unsigned int; boost::optional<T>::rval_reference_type = unsigned int&&] <near match>
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
^ ~~~~
/opt/boost/include/boost/optional/optional.hpp:805:1: note: conversion of argument 1 would be ill-formed:
a.cu:2:53: error: invalid conversion from ‘const boost::none_t (*)(boost::none_t::init_tag (*)())’ to ‘unsigned int’ [-fpermissive]
void foo(boost::optional<unsigned> x = boost::none);
^
/opt/boost/include/boost/optional/optional.hpp:800:1: note: candidate: boost::optional<T>::optional(boost::optional<T>::argument_type) [with T = unsigned int; boost::optional<T>::argument_type = const unsigned int&] <near match>
optional ( argument_type val ) : base(val) {}
^ ~~~~
/opt/boost/include/boost/optional/optional.hpp:800:1: note: conversion of argument 1 would be ill-formed:
a.cu:2:53: error: invalid conversion from ‘const boost::none_t (*)(boost::none_t::init_tag (*)())’ to ‘unsigned int’ [-fpermissive]
void foo(boost::optional<unsigned> x = boost::none);
Why does this happen, and can I circumvent the problem while still actually using boost::optional in (host-side) code compiled with nvcc?
Additional information:
The code compiles fine with g++ 6.3.0 (my distribution's compiler).
This code (or rather, similar code) used to compile and work on an earlier Linux distribution I was using, where the compiler was g++ 5.4.x .
I've tried this with Boost versions 1.65.1 and 1.69.0 .
I've tried this with CUDA versions 9.2.88 and 10.0.130 .
I had the exact same error and was able to get this to work with this modification:
#define BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
#include <boost/optional.hpp>
This is using CUDA 10.0.130, g++ 7.3.0, and Boost 1.68.0.
A partial answer to the second question:
You could consider using Andrzej Krzemieński's neat and self-contained implementation of an optional instead of boost::optional. It works with C++11, which is what you seem to be doing.
I have a very simple 'issue' with LibSVM:
I am on a Mac, OSX, 10.9.5. I cloned the libSVM repo from here, and as per the instructions on the README, simply ran make.
This is supposed to compile the libSVM programs without issue, but I am getting a litany of warnings about signedness.
Needless to say, this concerns me, because of signs are changing willy nilly, I will have no faith in the classifier. Should this be something of concern, and if so, how do I go about resolving it?
Here is what I get when I run the make command from the command line:
adam-MacBook-Pro:libsvm adam$ make
c++ -Wall -Wconversion -O3 -fPIC -c svm.cpp
svm.cpp:96:26: warning: implicit conversion changes signedness: 'int' to 'size_t' (aka 'unsigned long') [-Wsign-conversion]
head = (head_t *)calloc(l,sizeof(head_t)); // initialized to 0
~~~~~~ ^
svm.cpp:98:10: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion]
size -= l * sizeof(head_t) / sizeof(Qfloat);
^ ~
svm.cpp:146:54: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion]
h->data = (Qfloat *)realloc(h->data,sizeof(Qfloat)*len);
~^~~
svm.cpp:1651:38: warning: implicit conversion changes signedness: 'const int' to 'unsigned long' [-Wsign-conversion]
double *alpha = Malloc(double,prob->l);
~~~~~~~~~~~~~~~~~~~~^~
svm.cpp:39:40: note: expanded from macro 'Malloc'
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
^
svm.cpp:1722:26: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion]
double *t=Malloc(double,l);
~~~~~~~~~~~~~~^~
svm.cpp:39:40: note: expanded from macro 'Malloc'
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
^
svm.cpp:1833:29: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion]
In the following code from Stroustrup's book we are warned against an error from a narrowing conversion which does not occur on my version GCC (4.7.2)
#include <iostream>
using namespace std;
int main()
{
int i1 = 7.2;
int i2{7.2};
cout << i1 << " " << i2 << endl;
return 0;
}
As demonstrated here at ideone is this a bug or am I not running with the appropriate command line arguments to the compiler? Or is this meant to be a purely semantic error?
With g++ 4.8.1:
foo.cpp: In function 'int main()':
foo.cpp:8:15: warning: narrowing conversion of '7.2000000000000002e+0' from 'double' to 'int' inside { } [-Wnarrowing]
int i2{7.2};
^
I assume it's simply a bug in 4.7.2's c++11 support.
I get a narrowing warning with GCC 4.7.3 when I use -std=c++0x:
g++ -std=c++0x test.cpp
test.cpp: In function ‘int main()’:
test.cpp:8:23: warning: narrowing conversion of ‘7.2000000000000002e+0’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
g++ --version
g++ (GCC) 4.7.3
Hi I get the following warnings
g++ -std=c++0x -Wall -c -I/usr/local/boost_1_53_0 -I/home/aditya/CodeBase/includes MAIN.cpp
In file included from /usr/local/boost_1_53_0/boost/interprocess/detail/managed_open_or_create_impl.hpp:15:0,
from /usr/local/boost_1_53_0/boost/interprocess /managed_shared_memory.hpp:22,
from MAIN.cpp:22:
/usr/local/boost_1_53_0/boost/interprocess/detail/os_thread_functions.hpp: In function ‘void boost::interprocess::ipcdetail::thread_sleep(unsigned int)’:
/usr/local/boost_1_53_0/boost/interprocess/detail/os_thread_functions.hpp:169:65: warning: narrowing conversion of ‘(ms / 1000u)’ from ‘unsigned int’ to ‘__time_t {aka long int}’ inside { } [-Wnarrowing]
/usr/local/boost_1_53_0/boost/interprocess/detail/os_thread_functions.hpp:169:65: warning: narrowing conversion of ‘((ms % 1000u) * 1000000u)’ from ‘unsigned int’ to ‘long int’ inside { } [-Wnarrowing]
on compiling the following program
#include <iostream>
#include <memory>
#include <boost/thread.hpp>
#include <boost/managed_shared_memory.hpp>
int main(){
return 0;
}
I'm using gcc 4.7 on an ubuntu 12.04