C++ - 所有隐式转换的编译错误

C++ - compilation error for all implicit conversion

本文关键字:转换 编译 错误 C++      更新时间:2023-10-16

是否有编译器标志在发生任何隐式转换时记录警告/错误 - 例如int32_t到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

我在编译过程中没有遇到任何问题/警告/错误 - 有没有办法实现。

uint32_t i = x;
有符号 int

类型到无符号 int 类型的转换在 C++ 中得到了很好的定义。

(C++11, §4.7 ¶2(

如果目标类型为无符号,则结果值最小 与源整数全等的无符号整数(模 2 n,其中n 是用于表示无符号类型的位数(。[注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断(。

我不知道有

哪个编译器提供这样的标志(尽管我总是有可能错过一个(。

缺少它,您可以构建一个小模板,至少在以下几种明显情况下无法进行这种隐式转换:

#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";
}

尝试使用 g++ 进行编译会得到:

trash9.cpp:20:23: error: conversion from 'holder<int>' to non-scalar type 'holder<unsigned int>' requested
  holder<uint32_t> i = x;
                       ^

但是,如果我们更改第二个以holder<int32_t> i = x;则一切正常并按预期运行。

这对于您提供的演示代码来说已经足够了,但并非在所有情况下都有效。特别是,在计算表达式的过程中仍允许隐式转换:

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);
}

如果你想在这种情况下防止转换,你可以这样做,但这将需要更多的工作 - 你需要从上面的代码中删除operator Toperator T&,然后实现你想要支持的所有运算符。这可能会很乏味,以至于至少是轻微的痛苦,但无论如何你都可能会发现它是可以接受的。