Reputation: 8717
Is there a compiler flag that logs warning / error in case of any implicit conversions - like int32_t to uint32_t.
#include <cstdint>
#include <iostream>
using ::std::int32_t;
using ::std::uint32_t;
int main(int argc, char *argv[])
{
int32_t x = 9;
uint32_t i = x;
std::cout << " " << x << " " << i << std::flush << std::endl;
return 0;
}
c++ -std=c++11 -Wall -Wconversion -Wpedantic cast.cpp
I get no issues / warning / error during compilation - is there a way it can achieved.
Upvotes: 0
Views: 419
Reputation: 490208
I don't know of a compiler that provides such a flag (though it's always possible I've missed one).
Lacking it, you could build a little template that will make such implicit conversions impossible in at least a few obvious situations:
#include <cstdint>
#include <iostream>
using ::std::int32_t;
using ::std::uint32_t;
template <class T>
class holder {
T value;
public:
holder(T value) : value(value) {}
operator T&() { return value; }
operator T() const { return value; }
holder &operator=(holder const &other) { value = other.value; return *this; }
};
int main(int argc, char *argv[]) {
holder<int32_t> x = 9;
holder<uint32_t> i = x;
++i;
std::cout << " " << x << " " << i << "\n";
}
Attempting to compile with g++ gives:
trash9.cpp:20:23: error: conversion from 'holder<int>' to non-scalar type 'holder<unsigned int>' requested
holder<uint32_t> i = x;
^
If, however, we change the second to holder<int32_t> i = x;
it all works fine and acts as expected.
This suffices for the demo code you've given, but won't work in all situations. In particular, an implicit conversion in the course of evaluating an expression will still be allowed:
void use(holder<uint32_t> v) {
std::cout << v;
}
int main(int argc, char *argv[]) {
holder<int32_t> x = 9;
holder<int32_t> i = x;
use(i | 1u);
}
If you want to prevent conversions in cases like that as well, you can do it, but it's going to be a lot more work--you'll need to remove the operator T
and operator T&
from the code above, and then implement all the operators you do want to support. That would/will probably be tedious to the point that it's at least mildly painful, but you might find it acceptable anyway.
Upvotes: 1
Reputation: 4106
uint32_t i = x;
Signed int type to unsigned int type conversion is well defined in C++.
(C++11, §4.7 ¶2)
If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). — end note ]
Upvotes: 2