Original Post
🔒 Locked
C++ generating warning/error with unsigned math
Advertisement
You won't be able to overload with built-in types. There is a pragma to cause a specific warning to become an error. You might be able to do it for the sign/unsigned mismatch warning.
Look for something like:
#pragma warning(push)
#pragma warning(error: XXXXX)
// Your math code here
#pragma warning(pop)
Look for something like:
#pragma warning(push)
#pragma warning(error: XXXXX)
// Your math code here
#pragma warning(pop)
Quote:
Original post by zedz
with msvc
is it possible to generate an error if code trys to do math with an unsigned number
eg
uint32 a=0;
a+=X; // error
( notw - of course I could make my own type + override the operators but thats obviously messy )
ta zed
If you define your own type, you don't have to override operators. In fact, when you write your own type, you have to define those operators explicitly.
To forbid unsigned math, two solutions come to mind:
template
template <typename T> class restricted {public: operator T () const { return data; } restricted (T const &data_) : data (data_) {} restricted(restricted const &r) : data (r.data) {}private: restricted(); restricted & operator = (restricted const &); T data;};int main () { restricted<unsigned int> a = 5; // okay unsigned int X = a; // okay a += X; // die typedef restricted<unsigned int> cuint_t; cuint_t c = 5; // okay cuint_t d = c; // okay c += c; // die}You can then cherry pick which operators you want to allow or forbid.
Or, if you just want to forbid anything but initialization, make it const:
const
int main () { typedef const unsigned int cuint; cuint a = 5; cuint b = a; a += b;}
I'd be more tempted with the following changes:
To avoid:
This is also possibly tempting, but probably not needed:
the pair of which may be useful, or may just get in the way.
Finally, these are rather useful:
which, I'll admit, the operator T in the original, together with an implicit construction from T, would make not-useful in the prior implementation.
Basically you can have lots of control over your custom data type. You get compiler errors when someone tries to do something you don't allow.
You do have to be careful about implicit conversion of types. When you are making a restricted type, making these conversions explicit and manual can avoid the compiler 'working around your restrictions' possibly in ways you did not intend...
// remove operator T, add: T get() const { return data; }To avoid:
restricted<unsigned int> foo;int x += foo; // works under old versionThis is also possibly tempting, but probably not needed:
// no implicit conversion from T: (you may not want this!) explicit restricted (T const &data_) : data (data_) {}[...]// function to convert an expression to T:template<typename T>restricted<T> restrict( T const& data ) { return restricted<T>(data); }the pair of which may be useful, or may just get in the way.
Finally, these are rather useful:
// allow explicit conversion from sufficiently similar types: // explicit is optional. template<typename U> explicit restricted (U const &data_) : data (data_) {} // allow explicit conversion from another restricted type that is // sufficiently related: (should probably stay explicit) template<typename U> explicit restricted (restricted<U> const& src) : data( src.get() ) {}which, I'll admit, the operator T in the original, together with an implicit construction from T, would make not-useful in the prior implementation.
Basically you can have lots of control over your custom data type. You get compiler errors when someone tries to do something you don't allow.
You do have to be careful about implicit conversion of types. When you are making a restricted type, making these conversions explicit and manual can avoid the compiler 'working around your restrictions' possibly in ways you did not intend...
If you made your own type, you could use a templated operator + and type traits to solve the problem.
You would need TR1 support for type traits (VS2008 SP1 has it, or Boost, or compiler intrinsics), and a static_assert (C++0x or build your own). But you will generate error messages this way.
Just an idea.
template <typename T>const MyType operator + (const T &rhs) const{ static_assert( std::tr1::is_signed<T>, "Unsigned numbers not allowed." ); return data + rhs;}You would need TR1 support for type traits (VS2008 SP1 has it, or Boost, or compiler intrinsics), and a static_assert (C++0x or build your own). But you will generate error messages this way.
Just an idea.
>> If you define your own type, you don't have to override operators. In fact, when you write your own type, you have to define those operators explicitly.
you are of course correct
>> Or, if you just want to forbid anything but initialization, make it const:
that would be sweet unfortunately I also want to be able to assign a number to it
thanks guys, looks like the only way is for me to create my own type
you are of course correct
>> Or, if you just want to forbid anything but initialization, make it const:
that would be sweet unfortunately I also want to be able to assign a number to it
thanks guys, looks like the only way is for me to create my own type
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement