检测初始化变量

时间:2018-12-01 00:59:46

标签: c++ initialization

有没有一种方法可以检查某个变量是否在程序中某个点之前被初始化了?

例如,如何检查某个变量是否在IfStmt节点之前的某个位置初始化? 由于以下情况,VarDecl类(hasInit()getInit())中的方法还不够:

int x = 0; // hasInit() return true

int y;
...
y = 0; // initialized here, but hasInit() returns false
...
if (...) {}

2 个答案:

答案 0 :(得分:1)

如果您维护用C ++代码编写的产品,并希望删除难看的不确定变量,则合理的方法是定义一个初始化函数或lambda f,然后将局部变量声明为{{1} }。

OTOH,如果您故意故意延迟值分配 ,则有几种方法可以检测到是否分配了值。 我只是想出了以下方法。


std ::可选

在C ++ 17及更高版本中, const auto x = f(...);使我们能够检测是否分配了值。 std::optional<T>std::optional::has_value分别对应于您的std::optional::valuehasInit,如下所示:

DEMO

getInit

输出如下:

  

值仍未分配。

     

值由1分配。


std :: unique_ptr

我们还可以使用C ++ 11中引入的#include <iostream> #include <optional> template<typename T> void checkInitialization(const std::optional<T>& a) { if(a.has_value()){ std::cout << "Value is assigned by " << a.value() << "." << std::endl; } else{ std::cout << "Value is still not assigned." << std::endl; } } int main(void) { std::optional<int> x; checkInitialization(x); // Value is still not assigned x = 1; checkInitialization(x); // Value is assigned return 0; } 进行检查。 首先,我们将变量定义为std::unique_ptr<T>,其中std::unique_ptr<T> x;仍然为true。 稍后,我们用(x == nullptr)分配一个值,然后x = std::unique_ptr<int>(new int(1))变为false。 (在C ++ 14中,(x == nullptr)有效且简单。) 因此,我们可以使用以下代码再次获得先前的输出:

DEMO

x = std::make_unique<int>(1)

std :: pair

我们也可以应用#include <iostream> #include <memory> template<typename T> bool hasInit(const std::unique_ptr<T>& a) { return (a != nullptr); } template<typename T> const T& getInit(const std::unique_ptr<T>& a) { return *a; } template<typename T> void checkInitialization(const std::unique_ptr<T>& a) { if(hasInit(a)){ std::cout << "Value is assigned by " << getInit(a) << "." << std::endl; } else{ std::cout << "Value is still not assigned." << std::endl; } } int main(void) { std::unique_ptr<int> x; checkInitialization(x); // Uninitialized x = std::unique_ptr<int>(new int(1)); //x = std::make_unique<int>(1); // C++14 checkInitialization(x); // Initialized return 0; } ,其中std::pair<bool, T>std::pair::first分别对应于您的std::pair::secondhasInit。 我们再次获得先前的输出:

DEMO

getInit

答案 1 :(得分:1)

首先,如评论中所述:

let s = "x=a&y=b&z=c>=5";
console.log(s.split(/(?<!>|<)=/g));

假设您要检测分配。一种简单的方法是将要跟踪的整数包装在结构中并编写自定义int y = 0; // initialization int y; y = 0; // assignment 。例如:

operator = (int)

现在让我们看看会发生什么:

struct Foo 
{
   Foo() {std::cout << "default init" << std::endl;} 
   Foo& operator = (int elem) 
   { 
      cout<<"Int-Assignment operator called "<<endl;
      x = elem;
      is_assigned = true;
      return *this;
   }
   int x = 0; // default initialized to 0
   bool is_assigned = false; // default initialized to false
}; 

您可以使用类似这样的东西,也可以根据需要使用其他形式。这是与上述内容相对应的code running online

这是您想要的吗?